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

时间:2016-08-09 09:55:58

标签: java constructor mocking mockito

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

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

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

verify(myClass, times(1)).doSomething(anotherObject);

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

7 个答案:

答案 0 :(得分:16)

您可以使用Mockito和PowerMockito进行此操作。

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

public class ClassUnderTest {
    String name;
    boolean condition;

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

    ...
}

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

public class MyClass {

    public MyClass() { } 

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

    ...
}

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

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

@RunWith(PowerMockRunner.class)
@PrepareForTest({ ClassUnderTest.class, MyClass.class })
public class TestClass {

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

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

(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);
}

答案 1 :(得分:11)

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

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

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

答案 2 :(得分:2)

constructor方法等待模拟对象(已创建的对象)。 created object无法调用if(version.major === 0) { document.write('Du benutzt aktuell keinen Flash Player! '); flashPlayerVersion.style.display = 'none'; }

答案 3 :(得分:1)

这对Mockito来说是不可能的,听起来像是一个糟糕的设计。

您可以使用工厂并将其传递给测试对象。之后,您可以轻松地模拟工厂并验证其create方法是否已被调用。

通过在代码中直接创建对象,您将对具体实现产生一种硬依赖性,这使得代码更难以进行单元测试。这通过依赖注入(DI)和控制反转(IoC)来解决。

答案 4 :(得分:0)

构造函数如果失败则不会返回对象...如果失败,程序很可能会崩溃。

我认为这样做会很难:

Object obj = null;

obj = new Object();

if (obj == null) {
  //... Didn't Work
} else {
  //... Worked
}

答案 5 :(得分:0)

你将无法使用mockito模拟构造函数,但使用powermockito你应该能够然后验证它。设置将是这样的

public class MyClass{

   public MyClass(String name){}

   public void doSomethingUseFul(){
      //.......
   }

}

public class Helper {

   public void goHelp(){
       new MyClass("apple").doSomethingUseFul();
   } 

}

//模拟

    @RunWith(PowerMockRunner.class)
    @PrepareForTest(MyClass.class)
    public class MockMyClass {
    @InjectMocks
    private Helper helper;

        @Test
        public void testDoSomethingUseFul() {
             MyClass  c = mock(MyClass.class); 
             doNothing().when(c).doSomethingUseFul();
             PowerMockito.whenNew(MyClass. class).withArguments(anyString()).thenReturn(c);
             helper.goHelp(); 
             verifyNew(MyClass.class).withArguments(anyString())


        }
    }

答案 6 :(得分:0)

我们可以使用Mockito与

进行测试
verify(MyClass.class,times(1)).newInstance();