Mockito:如何测试构造函数被调用?

jav*_*999 9 java constructor mocking mockito

我正在使用Mockito来测试Java应用程序中的方法.

如何测试构造函数被调用一次?

我正在尝试进行类似的验证:

verify(myClass, times(1)).doSomething(anotherObject);
Run Code Online (Sandbox Code Playgroud)

但我无法验证构造函数是否被调用,因为它没有类似于例如的方法doSomething().

Jos*_*ino 16

你可以用Mockito和PowerMockito来做.

假设你有一个构造函数的ClassUnderTest

public class ClassUnderTest {
    String name;
    boolean condition;

    public ClassUnderTest(String name, boolean condition) {
       this.name = name;
       this.condition = condition;
       init();
    }

    ...
}
Run Code Online (Sandbox Code Playgroud)

另一个调用该构造函数的类

public class MyClass {

    public MyClass() { } 

    public void createCUTInstance() {
       // ...
       ClassUnderTest cut = new ClassUnderTest("abc", true);
       // ...
    }

    ...
}
Run Code Online (Sandbox Code Playgroud)

在Test课上我们可以......

(1)使用PowerMockRunner并在PrepareForTest注释中引用上面的两个目标类:

@RunWith(PowerMockRunner.class)
@PrepareForTest({ ClassUnderTest.class, MyClass.class })
public class TestClass {
Run Code Online (Sandbox Code Playgroud)

(2)拦截构造函数以返回一个模拟对象:

@Before
public void setup() {
    ClassUnderTest cutMock = Mockito.mock(ClassUnderTest.class);
    PowerMockito.whenNew(ClassUnderTest.class)
                .withArguments(Matchers.anyString(), Matchers.anyBoolean())
                .thenReturn(cutMock);
}
Run Code Online (Sandbox Code Playgroud)

(3)验证构造函数调用:

@Test
public void testMethod() {
    // prepare
    MyClasss myClass = new MyClass();

    // execute
    myClass.createCUTInstance();

    // checks if the constructor has been called once and with the expected argument values:
    String name = "abc";
    String condition = true;
    PowerMockito.verifyNew(ClassUnderTest.class).withArguments(name, condition);
}
Run Code Online (Sandbox Code Playgroud)


use*_*090 12

使用 Mockito 可以做一些事情

try (MockedConstruction<MyClass> myclass = Mockito.mockConstruction(
        MyClass.class)) {
    ........
    Assert.assertEquals(1, myClass.constructed().size());
}
Run Code Online (Sandbox Code Playgroud)


Stu*_*ion 11

这不能用Mockito完成,因为正在创建的对象不是模拟对象.这也意味着您将无法验证该新对象上的任何内容.

我过去通过使用a Factory创建对象而不是新建对象来解决这个问题.然后,您可以模拟Factory返回测试所需的对象.

您是否乐意改变您的设计以适应您的测试取决于您!