使用JUnit 4的预期exception机制导致意外行为的原因?

我试图测试一个特定的方法从方法抛出预期的exception。 根据JUnit4文档和这个答案,我把测试编写为:

@Test(expected=CannotUndoException.class) public void testUndoThrowsCannotUndoException() { // code to initialise 'command' command.undo(); } 

但是,此代码未通过JUnit测试,将抛出(和预期)exception报告为错误。

我正在测试的方法只有在体内:

 public void undo() { throw new CannotUndoException(); } 

此外,以下测试通过:

 public void testUndoThrowsCannotUndoException() { // code to initialise 'command' try { command.undo(); fail(); } catch (CannotUndoException cue){ } } 

意味着实际抛出了预期的exception。

我实际上计划将方法更改为实际执行某些操作,而不是仅仅抛出exception,但是让我对导致问题的原因感到好奇,以免将来再次发生。

已进行以下检查:

  • 导入到测试用例中的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 – 这可能是这里的罪魁祸首(尝试从命令行启动或在运行测试时直观地检查命令行)。 testrunner的类路径可能与项目类路径不同

在IDE中尤其如此。 或者你也可以尝试推送到junit 4.4,看看是否能解决你的问题。 (junit 4.5可能会导致其他问题)。

我有类似的问题,我通过添加注释修复它

 @RunWith(JUnit4ClassRunner.class) 

这告诉unit testing人员使用4er版本的Junit运行它

好奇。

我写了三个class:

撤消命令:

 public class UndoCommand { public void undo() { throw new CannotUndoException(); } } 

一个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。

你们有什么不同?