使用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。
你们有什么不同?