JMockit 连续期望
JMockit consecutive expectations
我最近遇到了下面解释的问题,但找不到解释。我的被测代码看起来不错,但测试失败了。我花了一段时间才明白出了什么问题,特别是因为我的测试代码并不像下面介绍的那么简单。
我正在与大家分享它,希望能找到一些解释并得出结论它是 JMockit 错误还是期望的行为,因此在实施我们的测试时需要注意一些事情。
代码中的注释将显示问题所在。
提前感谢您的意见。
package my.tst.pkg;
import mockit.Expectations;
import mockit.Mocked;
import org.testng.annotations.Test;
import java.util.Collection;
import static java.util.Arrays.asList;
import static org.testng.AssertJUnit.assertFalse;
public class ConsecutiveExpectationsTest {
class KeyHolder{
private String key;
String getKey() {
return key;
}
}
class ClassUnderTest {
private Collection<KeyHolder> keyHolders;
ClassUnderTest(Collection<KeyHolder> keyHolders) {
this.keyHolders = keyHolders;
}
boolean isValid() {
// At least one holder with no key means invalid
return !keyHolders.stream().filter(kh -> kh.getKey() == null).findFirst().isPresent();
}
}
@Mocked
KeyHolder keyHolder;
@Test
public void shouldBeInvalidIfNullKey() throws Exception {
new Expectations() {{
// This expectations fail the test
keyHolder.getKey(); returns("KEY", null);
// However if casting the null to a String the test will pass
// Is this something we should always do?
// keyHolder.getKey(); returns("KEY", (String) null);
}};
assertFalse(new ClassUnderTest(asList(keyHolder, keyHolder)).isValid());
}
}
这是 Java 语言使用不明确的情况,(体面的)Java IDE 应该向用户报告。
IntelliJ,一方面,报告 "Confusing 'null' argument to var-arg method" 警告。
这是 confusing/ambiguous 因为 returns(...)
方法的第二个参数是一个 Object... remainingValues
可变参数(在字节码中只是一个数组),并且由于 Java 编译器为调用构建数组参数。如果您只是传递 null
,编译器会将其解释为 (Object[]) null
, 而不是您所期望的 作为 new Object[] {null}
。将其转换为 String
消除了歧义,迫使编译器生成一个包含一个 null
元素的数组。
也就是说,JMockit 可以将空 Object[]
参数解释为等同于单元素数组。此更改可能会出现在未来的版本中;现在,应该使用对特定元素类型的转换(对于那些使用 IntelliJ 的人来说,无论如何都需要避免代码检查警告)。
我最近遇到了下面解释的问题,但找不到解释。我的被测代码看起来不错,但测试失败了。我花了一段时间才明白出了什么问题,特别是因为我的测试代码并不像下面介绍的那么简单。
我正在与大家分享它,希望能找到一些解释并得出结论它是 JMockit 错误还是期望的行为,因此在实施我们的测试时需要注意一些事情。
代码中的注释将显示问题所在。
提前感谢您的意见。
package my.tst.pkg;
import mockit.Expectations;
import mockit.Mocked;
import org.testng.annotations.Test;
import java.util.Collection;
import static java.util.Arrays.asList;
import static org.testng.AssertJUnit.assertFalse;
public class ConsecutiveExpectationsTest {
class KeyHolder{
private String key;
String getKey() {
return key;
}
}
class ClassUnderTest {
private Collection<KeyHolder> keyHolders;
ClassUnderTest(Collection<KeyHolder> keyHolders) {
this.keyHolders = keyHolders;
}
boolean isValid() {
// At least one holder with no key means invalid
return !keyHolders.stream().filter(kh -> kh.getKey() == null).findFirst().isPresent();
}
}
@Mocked
KeyHolder keyHolder;
@Test
public void shouldBeInvalidIfNullKey() throws Exception {
new Expectations() {{
// This expectations fail the test
keyHolder.getKey(); returns("KEY", null);
// However if casting the null to a String the test will pass
// Is this something we should always do?
// keyHolder.getKey(); returns("KEY", (String) null);
}};
assertFalse(new ClassUnderTest(asList(keyHolder, keyHolder)).isValid());
}
}
这是 Java 语言使用不明确的情况,(体面的)Java IDE 应该向用户报告。
IntelliJ,一方面,报告 "Confusing 'null' argument to var-arg method" 警告。
这是 confusing/ambiguous 因为 returns(...)
方法的第二个参数是一个 Object... remainingValues
可变参数(在字节码中只是一个数组),并且由于 Java 编译器为调用构建数组参数。如果您只是传递 null
,编译器会将其解释为 (Object[]) null
, 而不是您所期望的 作为 new Object[] {null}
。将其转换为 String
消除了歧义,迫使编译器生成一个包含一个 null
元素的数组。
也就是说,JMockit 可以将空 Object[]
参数解释为等同于单元素数组。此更改可能会出现在未来的版本中;现在,应该使用对特定元素类型的转换(对于那些使用 IntelliJ 的人来说,无论如何都需要避免代码检查警告)。