Bence bu sorunun güncel bir cevaba ihtiyacı var, çünkü buradaki cevapların çoğu oldukça güncel değil.
İlk olarak OP'nin sorusuna:
Bence JUnit'e "beklenen istisna" konseptini eklemenin kötü bir hareket olduğu kabul edildi, çünkü bu istisna herhangi bir yerde ortaya çıkabilir ve testi geçecektir. Çok alana özgü istisnalar atarsanız (ve iddia ederseniz) işe yarar, ancak bu tür istisnaları yalnızca kesinlikle kusursuz olması gereken kod üzerinde çalışırken atarım - çoğu APIS, IllegalArgumentException
veya gibi yerleşik istisnaları atar. IllegalStateException
. Yaptığınız iki çağrı bu istisnaları potansiyel olarak ortaya çıkarabilirse, o zaman @ExpectedException
ek açıklama, istisnayı fırlatan yanlış satır olsa bile testinize yeşil çubuk verecektir!
Bu durum için buradaki diğerlerinin yazdığından emin olduğum bir sınıf yazdım, bu bir assertThrows
yöntem:
public class Exceptions {
private Exceptions(){}
public static void assertThrows(Class<? extends Exception> expectedException, Runnable actionThatShouldThrow){
try{
actionThatShouldThrow.run();
fail("expected action to throw " + expectedException.getSimpleName() + " but it did not.");
}
catch(Exception e){
if ( ! expectedException.isInstance(e)) {
throw e;
}
}
}
}
bu yöntem, istisna atılırsa basitçe geri döner ve testinizde daha fazla iddia / doğrulama yapmanızı sağlar.
java 8 sözdizimi ile testiniz gerçekten güzel görünüyor. Yöntemi kullanan modelimizdeki daha basit testlerden biri aşağıdadır:
@Test
public void when_input_lower_bound_is_greater_than_upper_bound_axis_should_throw_illegal_arg() {
AxisRange range = new AxisRange(0,100);
Runnable act = () -> range.setLowerBound(200);
assertThrows(IllegalArgumentException.class, act);
}
Bu testler biraz riskli çünkü "hareket et" adımı aslında herhangi bir eylem gerçekleştirmiyor, ancak bence anlam hala oldukça açık.
Ayrıca maven üzerinde , istisnaların atıldığını doğrulamak için sahte stil sözdizimini kullanan catch-exception adlı küçük bir kitaplık var . Güzel görünüyor, ancak dinamik vekillerin hayranı değilim. Bununla birlikte, sözdizimi o kadar zarif ki cazip kalır:
List myList = new ArrayList();
catchException(myList).get(1);
assert caughtException() instanceof IndexOutOfBoundsException;
Son olarak, bu konuya ulaşmak için karşılaştığım durum için, bazı koşullar karşılanırsa testleri görmezden gelmenin bir yolu var .
Şu anda JNA adlı bir java yerel kitaplık yükleme kitaplığı aracılığıyla çağrılan bazı DLL'ler almak için çalışıyorum, ancak derleme sunucumuz ubuntu'da. Bu tür bir geliştirmeyi JUnit testleri ile sürdürmeyi seviyorum - bu noktada "birimlerden" uzak olsalar bile -. Yapmak istediğim şey, yerel bir makinedeysem testi çalıştırmak, ancak ubuntu'daysak testi göz ardı etmek. JUnit 4'ün bunun için şu adı verilen bir hükmü vardır Assume
:
@Test
public void when_asking_JNA_to_load_a_dll() throws URISyntaxException {
Assume.assumeFalse(BootstrappingUtilities.isCircleCI());
URL url = DLLTestFixture.class.getResource("USERDLL.dll");
String path = url.toURI().getPath();
path = path.substring(0, path.lastIndexOf("/"));
NativeLibrary.addSearchPath("USERDLL", path);
Object dll = Native.loadLibrary("USERDLL", NativeCallbacks.EmptyInterface.class);
assertThat(dll).isNotNull();
}