首页 文章

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

提问于
浏览
0

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

由于 programming error (缺少'throw'条款)这个 exception is not thrown . 由于测试用例设置包括使用jmockit 1.29的模拟类,因此稍后在方法中抛出NullPointerException .

shwoing基本类布局的示例类:

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);
        }
    }
}

所以我希望测试失败 . 但它确实成功了 . 删除测试注释的"(expected = ...)"部分会导致测试失败并出现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的未解决问题,但没有找到匹配的问题 .

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

Update:

我改进了示例以显示我的代码的相关细节 . 不幸的是,上面粘贴的代码确实表现得如预期,即显示错误:

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发布(4.6.1)

  • java版本"1.8.0_112" 64位

  • Windows 10

1 回答

  • 0

    在有用的评论之后,我发现问题可以缩小到"'false positive' problem with annotation based exception checking with Junit4":

    在再次检查完整的堆栈跟踪和包含抽象超类的代码之后,我在记录之后 found a try/catch converting any exception to MyException . 因此,从工具和代码的角度来看,一切都是可以预期的 .

相关问题