使用 JUnit 4 的预期异常机制导致意外行为的原因?
-
23-08-2019 - |
题
我正在尝试测试特定方法是否会从方法中引发预期异常。根据 JUnit4 文档和 这个答案 我将测试写为:
@Test(expected=CannotUndoException.class)
public void testUndoThrowsCannotUndoException() {
// code to initialise 'command'
command.undo();
}
但是,此代码未通过 JUnit 测试,并将抛出的(和预期的)异常报告为错误。
我正在测试的方法体内只有这个:
public void undo() {
throw new CannotUndoException();
}
此外,以下测试通过:
public void testUndoThrowsCannotUndoException() {
// code to initialise 'command'
try {
command.undo();
fail();
} catch (CannotUndoException cue){
}
}
这意味着预期的异常实际上被抛出了。
我实际上计划更改方法来实际执行某些操作,而不仅仅是抛出异常,但这让我很好奇导致问题的原因,以免将来再次发生。
已进行以下检查:
- 导入到测试用例中的 CannotUndoException 是正确的
- JUnit 的版本 4 是我的类路径上唯一的版本
- 干净且构建的 Eclipse 工作区并没有改变结果
我使用的是 JUnit 4.1,在同一个测试中我使用的是 Mockito。
什么可能导致错误的失败?
解决方案
我已经找到问题了。
我使用的 TestRunner 是正确的(JUnit 4),但是,我将我的测试类声明为:
public class CommandTest extends TestCase
我认为这会导致测试运行程序将其视为 JUnit 3 测试。我删除了 extends TestCase
并收到了预期的结果。
其他提示
你的测试代码对我来说看起来没问题。
检查您是否正在使用 junit 4 testrunner 运行,而不是 junit 3.8 testrunner - 这很可能是这里的罪魁祸首(尝试从命令行启动或在运行测试时仅目视检查命令行)。 您的测试运行器的类路径可能与您的项目类路径不同
在 IDE 内部尤其如此。或者,您也可以尝试推送到 junit 4.4,看看是否可以解决您的问题。(junit 4.5可能会导致其他问题)。
我有一个类似的问题,我通过添加注释修复了它
@RunWith(JUnit4ClassRunner.class)
它告诉单元测试人员使用 4er 版本的 Junit 运行它
好奇的。
我写了三个类:
撤消命令:
public class UndoCommand
{
public void undo()
{
throw new CannotUndoException();
}
}
无法撤消异常:
// Note: extends the unchecked superclass RuntimeException
public class CannotUndoException extends RuntimeException
{
public CannotUndoException()
{
super();
}
public CannotUndoException(String message)
{
super(message);
}
public CannotUndoException(String message, Throwable cause)
{
super(message, cause);
}
public CannotUndoException(Throwable cause)
{
super(cause);
}
}
以及 JUnit 4.4 测试类:
import org.junit.Test;
public class UndoCommandTest
{
@Test(expected=CannotUndoException.class)
public void testUndo()
{
UndoCommand command = new UndoCommand();
command.undo();
}
}
工作完美 - 所有测试均通过,“绿色”结果。
如果我从注释中删除 (expected=...) ,测试将按预期失败。
我正在使用 Sun JDK 6、JUnit 4.4 和 IntelliJ 7.0.5。
你的有何不同?