我遇到了一个问题 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 回答
在有用的评论之后,我发现问题可以缩小到"'false positive' problem with annotation based exception checking with Junit4":
在再次检查完整的堆栈跟踪和包含抽象超类的代码之后,我在记录之后 found a try/catch converting any exception to MyException . 因此,从工具和代码的角度来看,一切都是可以预期的 .