关于java:使用JUnit 4的预期异常机制导致意外行为的原因?

Cause of an unexpected behaviour using JUnit 4's expected exception mechanism?

我试图测试一个特定的方法是否从一个方法中抛出一个预期的异常。根据JUnit4文件和这个答案,我写的测试如下:

1
2
3
4
5
6
@Test(expected=CannotUndoException.class)  
public void testUndoThrowsCannotUndoException() {  
    // code to initialise 'command'

    command.undo();
}

但是,此代码未能通过JUnit测试,将引发的(和预期的)异常报告为错误。

我测试的方法在身体里只有这个:

1
2
3
public void undo() {
    throw new CannotUndoException();
}

此外,以下测试通过:

1
2
3
4
5
6
7
8
9
10
public void testUndoThrowsCannotUndoException() {
    // code to initialise 'command'

    try {
        command.undo();
        fail();
    } catch (CannotUndoException cue){

    }
}

这意味着实际抛出了预期的异常。

我实际上打算改变方法来做实际的事情,而不仅仅是抛出异常,但是它让我好奇是什么导致了这个问题,以免将来再次发生。

已进行以下检查:

  • 导入到测试用例中的cannotUndoException是正确的。
  • JUnit的第4版是我类路径上唯一的版本
  • 一个干净的Eclipse工作区的构建并没有改变结果。

我使用的是JUnit4.1,在同一个测试中,我使用的是Mockito。

什么可能导致错误的失败?


我发现了问题。

我使用的TestRunner是正确的(JUnit4),但是,我声明我的测试类为:

1
public class CommandTest extends TestCase

我认为这会导致测试运行程序将其视为JUnit3测试。我移除了extends TestCase,并收到了预期的结果。


我看你的测试代码没问题。

检查您运行的是JUnit 4测试运行程序,而不是JUnit 3.8测试运行程序-这很可能是这里的罪魁祸首(请尝试从命令行启动,或者在运行测试时只目视检查命令行)。测试运行程序的类路径可能与项目类路径不同

尤其是在IDE内部,您也可以尝试推到JUnit4.4,看看是否解决了您的问题。(JUnit 4.5可能会导致其他问题)。


我有一个类似的问题,我通过添加注释来解决它。

1
@RunWith(JUnit4ClassRunner.class)

它告诉单元测试人员使用JUnit的4er版本运行它。


好奇的。

我写了三节课:

UndoCommand:

1
2
3
4
5
6
7
public class UndoCommand
{
    public void undo()
    {
        throw new CannotUndoException();
    }
}

无法撤消的异常:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// 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测试类:

1
2
3
4
5
6
7
8
9
10
11
12
import org.junit.Test;

public class UndoCommandTest
{
    @Test(expected=CannotUndoException.class)
    public void testUndo()
    {
        UndoCommand command = new UndoCommand();

        command.undo();
    }
}

工作完美-所有测试通过,"绿色"结果。

如果我从注释中移除(预期=…)测试将失败,如预期的那样。

我使用的是Sun JDK 6、JUnit 4.4和IntelliJ 7.0.5。

你有什么不同?