JUnit4库中有一个fail()
方法。我喜欢它,但遇到缺少pass()
方法,而该方法在库中不存在。为什么会这样?
我发现我可以使用assertTrue(true)
代替但仍然看起来不合逻辑。
@Test
public void testSetterForeignWord(){
try {
card.setForeignWord("");
fail();
} catch (IncorrectArgumentForSetter ex){
}
// assertTrue(true);
}
答案 0 :(得分:62)
只要您的测试完成并通过,请致电 return
语句。
答案 1 :(得分:59)
只要测试没有抛出异常,它就会通过,除非你的@Test
注释指定了预期的异常。我认为pass()
可以抛出一个特殊的异常,JUnit总是将其解释为传递,以便使测试短路,但这会违反通常的测试设计(即假设成功,只有在断言失败时才会失败)并且,如果人们认为最好使用pass()
,那么它将大大减慢一大堆通过测试(由于异常创建的开销)。失败的测试不应该是常态,所以如果他们有这样的开销就没什么大不了的。
请注意,您的示例可以像这样重写:
@Test(expected=IncorrectArgumentForSetter.class)
public void testSetterForeignWord("") throws Exception {
card.setForeignWord("");
}
此外,您应该支持使用标准Java异常。您的IncorrectArgumentForSetter
应该是IllegalArgumentException
。
答案 2 :(得分:5)
我认为这个问题需要更新的答案,因为这里的大多数答案都已经过时了。
首先是OP的问题:
我认为它很好地接受了引入"预期的例外情况"进入JUnit的概念是一个糟糕的举动,因为该异常可以在任何地方提出,并且它将通过测试。如果您抛出(并断言)非常特定于域的异常,它会起作用,但是当我处理需要绝对完美无瑕的代码时,我只抛出这些异常, - 大多数APIS只会抛出内置的异常例如IllegalArgumentException
或IllegalStateException
。如果两个调用你的make可以有效地抛出这些异常,那么@ExpectedException
注释会对你的测试进行绿色调整,即使它是错误的行抛出异常!
对于这种情况,我写过一篇课程,我确信这里有很多其他人写过,这是一种assertThrows
方法:
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;
}
}
}
}
如果抛出异常,此方法只会返回,允许您在测试中进行进一步的断言/验证。
使用java 8语法,您的测试看起来非常好。以下是我们使用该方法的模型的简单测试之一:
@Test
public void when_input_lower_bound_is_greater_than_upper_bound_axis_should_throw_illegal_arg() {
//setup
AxisRange range = new AxisRange(0,100);
//act
Runnable act = () -> range.setLowerBound(200);
//assert
assertThrows(IllegalArgumentException.class, act);
}
这些测试有点不稳定因为&#34;行为&#34;步骤并没有实际执行任何操作,但我认为其含义仍然相当明确。
还有一个名为catch-exception的maven上的小型库,它使用mockito风格的语法来验证是否会抛出异常。它看起来很漂亮,但我不是动态代理的粉丝。也就是说,语法是如此光滑,它仍然很诱人:
// given: an empty list
List myList = new ArrayList();
// when: we try to get the first element of the list
// then: catch the exception if any is thrown
catchException(myList).get(1);
// then: we expect an IndexOutOfBoundsException
assert caughtException() instanceof IndexOutOfBoundsException;
最后,对于我遇到的这种情况,有一种方法可以在满足某些条件时忽略测试。
现在我正在努力通过一个名为JNA的java native-library-loading-library调用一些DLL,但是我们的构建服务器在ubuntu中。我喜欢尝试使用JUnit测试来推动这种开发 - 即使他们远离&#34;单位&#34;在此刻 - 。我想要做的是如果我在本地机器上运行测试,但如果我们在ubuntu上,则忽略测试。 JUnit 4确实有这样的规定,称为Assume
:
@Test
public void when_asking_JNA_to_load_a_dll() throws URISyntaxException {
//this line will cause the test to be branded as "ignored" when "isCircleCI"
//(the machine running ubuntu is running this test) is true.
Assume.assumeFalse(BootstrappingUtilities.isCircleCI());
//an ignored test will typically result in some qualifier being put on the results,
//but will also not typically prevent a green-ton most platforms.
//setup
URL url = DLLTestFixture.class.getResource("USERDLL.dll");
String path = url.toURI().getPath();
path = path.substring(0, path.lastIndexOf("/"));
//act
NativeLibrary.addSearchPath("USERDLL", path);
Object dll = Native.loadLibrary("USERDLL", NativeCallbacks.EmptyInterface.class);
//assert
assertThat(dll).isNotNull();
}
答案 3 :(得分:3)
我也在为JUnit寻找pass
方法,这样我就可以将某些不适用的测试短路(有集成测试,而不是纯单元测试)。太糟糕了,不存在。
幸运的是,有一种方法可以有条件地忽略测试,在我的情况下使用assumeTrue
方法实际上更合适:
Assume.assumeTrue(isTestApplicable);
所以这里只有当isTestApplicable为true时才会执行测试,否则测试将被忽略。
答案 4 :(得分:2)
不需要pass方法,因为当测试代码中没有抛出AssertionFailedException时,单元测试用例将通过。
如果控制到达那一点,fail()方法实际上会抛出AssertionFailedException以使testCase失败。
答案 5 :(得分:1)
我认为这个问题是对测试执行过程有点误解的结果。在JUnit(和其他测试工具)中,每个方法计算结果,而不是每个断言调用。没有计数器可以跟踪已执行的通过/未通过assertX
的次数。
JUnit分别执行每个测试方法。如果方法成功返回,则测试注册为“已通过”。如果发生异常,则测试注册为“失败”。在后一种情况下,两个子例程是可能的:1)JUnit断言异常,2)任何其他类型的异常。第一种情况下状态为“失败”,第二种情况为“错误”。
在Assert
类中,许多简写方法都可用于抛出断言异常。换句话说,Assert
是JUnit异常的抽象层。
例如,这是GitHub上assertEquals
的源代码:
/**
* Asserts that two Strings are equal.
*/
static public void assertEquals(String message, String expected, String actual) {
if (expected == null && actual == null) {
return;
}
if (expected != null && expected.equals(actual)) {
return;
}
String cleanMessage = message == null ? "" : message;
throw new ComparisonFailure(cleanMessage, expected, actual);
}
正如你所看到的,在平等的情况下没有任何事情发生,否则将抛出异常。
所以:
assertEqual("Oh!", "Some string", "Another string!");
只会抛出一个ComparisonFailure
异常,它将被JUnit捕获,并且
assertEqual("Oh?", "Same string", "Same string");
没有。
总而言之,像pass()
这样的东西没有任何意义,因为它没有做任何事情。