如何验证给定 class 的特定构造函数是否被调用?

How do I verify that a specific constructor of a given class is called?

假设以下是被测class:

public class MyClass {
    public void doSomething() throws FileNotFoundException {
        FileInputStream fis = new FileInputStream( "someFile.txt" );
        // .. do something about fis
    }
}

当使用 jMockit 以参数 "someFile.txt" 调用方法 doSomething() 时,如何验证构造函数 FileInputStream( String ) 被调用?

我不是在寻找手动或非自动的答案。我正在寻找一个答案,它使用 JUnit 或 TestNG 等工具在模拟和间谍工具(最好是 jMockit)的帮助下进行自动化单元测试。

您可以使用 JMockit 的 $init 来验证构造函数调用:

@Test
void testDoSomethingCallsConstructorWithStringArgument throws FileNotFoundException() {
    new MockUp<FileInputStream>() {
        @Mock(invocations = 1) // Verifies one call
        void $init(String file) {
            assertEquals("someFile.txt", file);
        }
    };

    // TODO Setup an object of MyClass
    myObject.doSomething();
}

(很遗憾,我目前无法测试)

使用 JMockit Expectations API,测试可以像方法调用一样验证构造函数调用。测试只需要将 class 指定为 @Mocked。例如:

@Test
public void exampleTestThatVerifiesConstructorCall(@Mocked FileInputStream anyFIS)
{
    new MyClass().doSomething();

    new Verifications() {{ new FileInputStream("someFile.txt"); }};
}

也就是说,我会建议避免模拟低级别的 classes,例如 FileInputStream,它们通常只是被测 class 的内部实现细节。更好的测试是使用实际文件并以某种方式检查它是否按预期读取。