具有预期异常的JUnit测试不符合预期

时间:2016-12-15 16:03:52

标签: java exception junit

我遇到了 JUnit 4.12的问题我在代码中测试一个应抛出特定异常的方法时无法解释。 我正在使用 @Test注释(expected = MyException.class)。 MyException只是从Exception派生而来。

由于编程错误缺少' throw'子句),此异常未被抛出。由于测试用例设置包括使用jmockit 1.29的模拟类,因此稍后在方法中抛出NullPointerException。

基本类布局的示例类:

package l00tr.test;

public class MyException extends Exception {
    private static final long serialVersionUID = 1L;
    public MyException(String msg) {
        super(msg);
    }
}

package l00tr.test;

import java.util.Map;
import java.util.Set;

public class MyClass {

    private Set<String> testSet;
    private Map<String, String> testMap;
    private boolean condition;

    private MyClass() {
        this.testSet = null;
        this.testMap = null;
        this.condition = false;
    }
    private MyClass(Set<String> testSet, Map<String, String> testMap,
            boolean condition) {
        this.testSet = testSet;
        this.testMap = testMap;
        this.condition = condition;
    }
    public void method() throws MyException {
        if (testSet.size() < 2) {
            throw new MyException("test set");
        }
        if (!condition) {
            // FORGOTTEN: throw
            new MyException("test");
        }
        System.out.print("set size: " + testSet.size());
        System.out.print("some more stuff succeeding");
        System.out.print("map size: " + testMap.size()); // NullPointerException
    }
    public static final class Builder {
        private Set<String> testSet;
        private Map<String, String> testMap;
        private boolean condition;
        private Builder() {
            this.testSet = null;
            this.testMap = null;
            this.condition = false;
        }
        public static Builder newBuilder() {
            return new Builder();
        }
        public Builder testSet(Set<String> testSet) {
            this.testSet = testSet;
            return this;
        }
        public Builder testMap(Map<String, String> testMap) {
            this.testMap = testMap;
            return this;
        }
        public Builder condition(boolean condition) {
            this.condition = condition;
            return this;
        }
        public MyClass build() {
            return new MyClass(testSet, testMap, condition);
        }
    }
}

所以我希望测试失败。但它确实成功了。删除测试注释的&#34;(expected = ...)&#34; 部分会导致测试失败并出现NullPointerException。

package l00tr.test;

import java.util.Set;
import org.junit.Test;
import mockit.Expectations;
import mockit.Mocked;

public class MyClassTests {
    @Mocked
    private Set<String> testSet;

    @Test(expected = MyException.class)
    public void testMethod() throws MyException {
        new Expectations() {
            {
                testSet.size();
                result = 3;
            }
        };
        MyClass mc = MyClass.Builder.newBuilder().condition(false)
                .testSet(testSet).build();
        mc.method();
    }
}

Jacoco帮助发现了这一点,否则我会错误地认为一切都很好。我还检查了junit 4.12的未解决问题,但没有找到匹配的问题。

为什么测试会成功?有什么想法吗?

更新

我改进了示例以显示我的代码的相关详细信息。不幸的是,上面粘贴的代码确实按预期运行,即显示错误:

java.lang.Exception: Unexpected exception, expected<l00tr.test.MyException> but was<java.lang.NullPointerException>

我的特定开发环境设置可能会发挥作用,因此这里有一些细节:

  • gradle 3.2.1 with active daemon
  • junit 4.12
  • jmockit 1.29
  • eclipse Neon.1a Release(4.6.1)
  • java版本&#34; 1.8.0_112&#34; 64位
  • Windows 10

1 个答案:

答案 0 :(得分:0)

在有用的评论之后,我发现问题可以缩小到使用Junit4进行基于注释的异常检查的“'误报'问题”

再次检查完整的堆栈跟踪和包含抽象超类的代码后,我在记录后发现了try / catch将任何异常转换为MyException 。因此,从工具和代码的角度来看,一切都可以预期。