JUnit4的fail()在这里,但是pass()在哪里?
JUnit4 库中有一个 fail()
方法。我喜欢它,但是缺少库中不存在的 pass()
方法。为什么会这样呢?
我发现我可以使用 assertTrue(true)
代替,但看起来仍然不合逻辑。
@Test
public void testSetterForeignWord(){
try {
card.setForeignWord("");
fail();
} catch (IncorrectArgumentForSetter ex){
}
// assertTrue(true);
}
There is a fail()
method in JUnit4 library. I like it, but experiencing a lack of pass()
method which is not present in the library. Why is it so?
I've found out that I can use assertTrue(true)
instead but still looks unlogical.
@Test
public void testSetterForeignWord(){
try {
card.setForeignWord("");
fail();
} catch (IncorrectArgumentForSetter ex){
}
// assertTrue(true);
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
测试完成并通过后,随时调用
return
语句。Call
return
statement anytime your test is finished and passed.只要测试不引发异常,它就会通过,除非您的
@Test
注释指定了预期的异常。我想 pass() 可能会抛出一个特殊的异常,JUnit 总是将其解释为通过,从而使测试短路,但这将违背测试的通常设计(即假设成功并且只失败如果断言失败),并且如果人们认为最好使用 pass() ,那么它将显着减慢大量通过测试的速度(由于异常创建的开销)。测试失败不应该是常态,所以如果有这样的开销也没什么大不了的。请注意,您的示例可以像这样重写:
另外,您应该赞成使用标准 Java 异常。您的
In CorrectArgumentForSetter
可能应该是IllegalArgumentException
。As long as the test doesn't throw an exception, it passes, unless your
@Test
annotation specifies an expected exception. I suppose apass()
could throw a special exception that JUnit always interprets as passing, so as to short circuit the test, but that would go against the usual design of tests (i.e. assume success and only fail if an assertion fails) and, if people got the idea that it was preferable to usepass()
, it would significantly slow down a large suite of passing tests (due to the overhead of exception creation). Failing tests should not be the norm, so it's not a big deal if they have that overhead.Note that your example could be rewritten like this:
Also, you should favor the use of standard Java exceptions. Your
IncorrectArgumentForSetter
should probably be anIllegalArgumentException
.我认为这个问题需要更新答案,因为这里的大多数答案都相当过时了。
首先针对 OP 的问题:
我认为将“预期异常”概念引入 JUnit 是一个糟糕的举动,因为该异常可以在任何地方引发,并且它将通过测试。如果您抛出(并断言)非常特定于域的异常,它会起作用,但我只在处理需要绝对完美的代码时抛出此类异常,--大多数 APIS 只会抛出内置异常,例如 <代码>IllegalArgumentException 或
IllegalStateException
。如果您进行的两次调用可能会引发这些异常,那么 @ExpectedException 注释将为您的测试设置绿条,即使抛出异常的行是错误的!对于这种情况,我编写了一个类,我相信这里的许多其他人都写过,这是一个
assertThrows
方法:如果抛出异常,该方法只是返回,允许您进行进一步的断言/验证在你的测试中。
使用 java 8 语法,您的测试看起来非常好。下面是使用该方法对我们的模型进行的更简单的测试之一:
这些测试有点奇怪,因为“act”步骤实际上并不执行任何操作,但我认为含义仍然相当清晰。
maven 上还有一个名为 catch-exception 的小库,它使用mockito-style语法来验证是否抛出异常。它看起来很漂亮,但我不喜欢动态代理。也就是说,语法非常流畅,仍然很诱人:
最后,对于我进入此线程时遇到的情况,有一种方法可以在满足某些条件时忽略测试。
现在我正在努力通过名为 JNA 的 java 本机库加载库调用一些 DLL,但我们的构建服务器位于 ubuntu 中。我喜欢尝试用 JUnit 测试来推动这种开发——尽管它们此时距离“单元”还很远——。我想做的是如果我在本地计算机上运行测试,但如果我们在 ubuntu 上则忽略测试。 JUnit 4 对此有一个规定,称为
Assume
:I think this question needs an updated answer, since most of the answers here are fairly outdated.
Firstly to the OP's question:
I think its pretty well accepted that introducing the "expected excepetion" concept into JUnit was a bad move, since that exception could be raised anywhere, and it will pass the test. It works if your throwing (and asserting on) very domain specific exceptions, but I only throw those kinds of exceptions when I'm working on code that needs to be absolutely immaculate, --most APIS will simply throw the built in exceptions like
IllegalArgumentException
orIllegalStateException
. If two calls your making could potentitally throw these exceptions, then the@ExpectedException
annotation will green-bar your test even if its the wrong line that throws the exception!For this situation I've written a class that I'm sure many others here have written, that's an
assertThrows
method:this method simply returns if the exception is thrown, allowing you to do further assertions/verification in your test.
with java 8 syntax your test looks really nice. Below is one of the simpler tests on our model that uses the method:
these tests are a little wonky because the "act" step doesn't actually perform any action, but I think the meaning is still fairly clear.
there's also a tiny little library on maven called catch-exception that uses the mockito-style syntax to verify that exceptions get thrown. It looks pretty, but I'm not a fan of dynamic proxies. That said, there syntax is so slick it remains tempting:
Lastly, for the situation that I ran into to get to this thread, there is a way to ignore tests if some conidition is met.
Right now I'm working on getting some DLLs called through a java native-library-loading-library called JNA, but our build server is in ubuntu. I like to try to drive this kind of development with JUnit tests --even though they're far from "units" at this point--. What I want to do is run the test if I'm on a local machine, but ignore the test if we're on ubuntu. JUnit 4 does have a provision for this, called
Assume
:我也在寻找 JUnit 的 pass 方法,这样我就可以短路一些在某些场景下不适用的测试(有集成测试,而不是纯粹的单元测试)。太糟糕了,它不在那里。
幸运的是,有一种方法可以有条件地忽略测试,这实际上更适合我使用
assumeTrue
方法的情况:所以这里只有当 isTestApplicable 为 true 时才会执行测试,否则测试将被忽略。
I was looking for
pass
method for JUnit as well, so that I could short-circuit some tests that were not applicable in some scenarios (there are integration tests, rather than pure unit tests). So too bad it is not there.Fortunately, there is a way to have a test ignored conditionally, which actually fits even better in my case using
assumeTrue
method:So here the test will be executed only if isTestApplicable is true, otherwise test will be ignored.
不需要 pass 方法,因为当测试代码中没有抛出 AssertionFailedException 时,单元测试用例就会通过。
如果控制到达该点,fail() 方法实际上会抛出 AssertionFailedException 以使 testCase 失败。
There is no need for the pass method because when no AssertionFailedException is thrown from the test code the unit test case will pass.
The fail() method actually throws an AssertionFailedException to fail the testCase if control comes to that point.
我认为这个问题是由于对测试执行过程的一些误解而产生的。在 JUnit(和其他测试工具)中,结果是按方法计算的,而不是按断言调用计算的。没有计数器可以跟踪执行了多少个通过/失败的
assertX
。JUnit 单独执行每个测试方法。如果该方法成功返回,则测试注册为“通过”。如果发生异常,则测试记录为“失败”。在后一种情况下,可能有两种子情况:1) JUnit 断言异常,2) 任何其他类型的异常。在第一种情况下,状态将为“失败”,在第二种情况下,状态将为“错误”。
在
Assert
类中,许多简写方法可用于引发断言异常。换句话说,Assert
是 JUnit 异常的抽象层。例如,这是 GitHub:
如你所见,在相等的情况下什么也不会发生,否则会抛出异常。
所以:
只是抛出一个 ComparisonFailure 异常,该异常将被 JUnit 捕获,并且
不执行任何操作。
总之,像
pass()
这样的东西没有任何意义,因为它没有做任何事情。I think that this question is a result of a little misunderstanding of the test execution process. In JUnit (and other testing tools) results are counted per method, not per assert call. There is not a counter, which keeps track of how many passed/failured
assertX
was executed.JUnit executes each test method separately. If the method returns successfully, then the test registered as "passed". If an exception occurs, then the test registered as "failed". In the latter case two subcase are possible: 1) a JUnit assertion exception, 2) any other kind of exceptions. Status will be "failed" in the first case, and "error" in the second case.
In the
Assert
class many shorthand methods are avaiable for throwing assertion exceptions. In other words,Assert
is an abstraction layer over JUnit's exceptions.For example, this is the source code of
assertEquals
on GitHub:As you can see, in case of equality nothing happens, otherwise an excepion will be thrown.
So:
simply throws a
ComparisonFailure
exception, which will be catched by JUnit, anddoes NOTHING.
In sum, something like
pass()
would not make any sense, because it did not do anything.