Java JUnit4 fail()在这里,但是pass()在哪里?
JUnit4库中有一个Java JUnit4 fail()在这里,但是pass()在哪里?,java,junit,Java,Junit,JUnit4库中有一个fail()方法。我喜欢它,但缺少库中不存在的pass()方法。为什么会这样 我发现我可以使用assertTrue(true)来代替,但看起来仍然不符合逻辑 @Test public void testSetterForeignWord(){ try { card.setForeignWord(""); fail(); } catch (IncorrectArgumentForSetter ex){ } // assertTrue(true);
fail()
方法。我喜欢它,但缺少库中不存在的pass()
方法。为什么会这样
我发现我可以使用assertTrue(true)
来代替,但看起来仍然不符合逻辑
@Test
public void testSetterForeignWord(){
try {
card.setForeignWord("");
fail();
} catch (IncorrectArgumentForSetter ex){
}
// assertTrue(true);
}
只要测试没有抛出异常,它就会通过,除非
@test
注释指定了预期的异常。我假设一个pass()
会抛出一个JUnit总是将其解释为通过的特殊异常,从而使测试短路,但这与通常的测试设计背道而驰(即假设成功,只有在断言失败时才会失败),如果人们认为最好使用pass()
,这将大大降低通过测试的大型套件的速度(由于异常创建的开销)。测试失败不应该成为常态,所以如果他们有这样的开销,那也没什么大不了的
请注意,您的示例可以这样改写:
@Test(expected=IncorrectArgumentForSetter.class)
public void testSetterForeignWord("") throws Exception {
card.setForeignWord("");
}
此外,您应该支持使用标准Java异常。您的
IncorrectArgumentForSetter
可能应该是一个IllegalArgumentException
不需要pass方法,因为当没有从测试代码抛出断言failedeexception时,单元测试用例将通过
fail()方法实际上抛出了一个断言FailedException,如果控制达到该点,则会使测试用例失败。在测试完成并通过时调用
返回
语句。我认为这个问题需要更新答案,因为这里的大多数答案都相当过时
首先,关于OP的问题:
我认为,在JUnit中引入“预期异常”概念是一个错误的举动,这一点已经被广泛接受,因为该异常可以在任何地方提出,并且它将通过测试。如果您抛出(并断言)非常特定于域的异常,它是有效的,但我只在处理需要绝对完美的代码时抛出这些类型的异常,-大多数API只会抛出内置异常,如IllegalArgumentException
或IllegalArgumentException
。如果您发出的两个调用可能会引发这些异常,那么@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;
}
}
}
}
这些测试有点不可靠,因为“act”步骤实际上没有执行任何操作,但我认为其含义仍然相当清楚
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本机库加载库调用一些DLL,但我们的构建服务器在ubuntu中。我喜欢尝试用JUnit测试来驱动这种开发——尽管在这一点上它们离“单元”很远。我想做的是,如果我在本地机器上运行测试,但是如果我们在ubuntu上则忽略测试。JUnit4对此有一个规定,称为假设:
@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();
}
我认为这个问题是对测试执行过程有点误解的结果。在JUnit(和其他测试工具)中,结果是按方法计算的,而不是按断言调用计算的。没有一个计数器,用于跟踪执行了多少通过/失败的assertX
JUnit分别执行每个测试方法。如果方法成功返回,则测试注册为“通过”。如果发生异常,则测试注册为“失败”。在后一种情况下,有两个子类是可能的:1)JUnit断言异常,2)任何其他类型的异常。第一种情况下的状态为“失败”,第二种情况下的状态为“错误”
在Assert
类中,许多速记方法可用于引发断言异常。换句话说,Assert
是JUnit异常之上的抽象层
例如,这是上的assertEquals
的源代码:
如您所见,在相等的情况下不会发生任何事情,否则将抛出一个例外
因此:
只需抛出一个comparisonfail
异常,JUnit将捕获该异常,然后
assertEqual("Oh?", "Same string", "Same string");
什么也不做
总之,像pass()
这样的东西没有任何意义,因为它没有做任何事情。我也在为JUnit寻找pass
方法,这样我就可以短路一些在某些场景中不适用的测试(有集成测试,而不是纯粹的单元测试)。可惜它不在那里
幸运的是,有一种方法可以有条件地忽略测试,它实际上更适合我使用assumeture
方法:
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;
}
}
}
}
假设。假设为真(不适用)
因此,这里只有当isTestApplicable为true时才会执行测试,否则测试将被忽略。fail()方法和assertX()方法实际上只是抛出一个断言错误,这会导致测试方法不干净地退出。这就是为什么一个成功的返回表示成功…-1-pass()方法不是什么都不做-它会立即退出测试,没有异常。在大多数情况下,这实际上相当于return语句(除了预期的异常、超时等)。@grigory:您是对的,pass()
方法不能什么都不做,以免调用后测试可能失败。所以我删除了那句话。我真是太感谢你了,帮助我摆脱了很多挫折+1.
assertEqual("Oh!", "Some string", "Another string!");
assertEqual("Oh?", "Same string", "Same string");