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 的人来说,无论如何都需要避免代码检查警告)。