PowerMockito - 构造函数调用的测试方法

时间:2014-08-19 18:47:24

标签: unit-testing constructor mockito powermock

我正在尝试为遗留代码编写测试。我要测试的其中一个类是构造函数。这个构造函数本身调用了其他几种方法。

我正在尝试为此构造函数编写单元测试,以验证构造函数调用的方法是否确实已被调用。

我在eclipse Luna Release(4.4.0)上使用PowerMock 1.5.5和Mockito 1.9.5与测试NG和eclipse(org.testng.eclipse - 6.8.6.20141201_2240)。

我可以请求指导我做错了吗? 我得到了例外:

  

想要但未被调用:classWithConstructor.doSomethingWithS();    - > at com.example.constructortester.MakerOfClassWithConstructorTest.testSomething(MakerOfClassWithConstructorTest.java:30)   实际上,这个模拟没有互动。

我期望doSomethingWithS应该被调用,但是我得到的错误消息告诉我Mock本身没有被使用,因此我期望在spy上调用的方法永远不会被调用。

以下是代码段:

具有构造函数的遗留类,后者又调用另一种方法

package com.example.constructortester;

public class ClassWithConstructor {

    public static final String MODIFIED = "Modified:";

    public ClassWithConstructor(String s) {
        String returnVal = doSomethingWithS(s);
        System.out.println("ClassWithConstructor::ClassWithConstructor - :"
                + returnVal);
    }

    protected String doSomethingWithS(String s) {
        System.out
                .println("ClassWithConstructor::doSomethingWithS - Something with s:"
                        + s);
        return MODIFIED + s;
    }
}

我用作构建器的课程:

package com.example.constructortester;

public class MakerOfClassWithConstructor {

    public MakerOfClassWithConstructor() {
    }

    public void doSomething(String s) {
        new ClassWithConstructor(s);
    }
}

最后,TestNG测试

package com.example.constructortester;

import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.testng.Assert.assertEquals;

import org.mockito.Mockito;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.testng.PowerMockTestCase;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;

@PrepareForTest(MakerOfClassWithConstructor.class)
public class MakerOfClassWithConstructorTest extends PowerMockTestCase {

    @Test
    public void testSomething() throws Exception {
        final String someString = "Test";
        final String someOtherString = "SomeOtherTest";

        ClassWithConstructor spyClassWithConstructor = spy(new ClassWithConstructor(
                someString));
        PowerMockito.whenNew(ClassWithConstructor.class)
                .withArguments(someString).thenReturn(spyClassWithConstructor);

        PowerMockito.doReturn(someOtherString).when(spyClassWithConstructor)
                .doSomethingWithS(someString);
        // PowerMockito.when(spyClassWithConstructor.doSomethingWithS(someString))
        // .thenReturn(someOtherString);

        new MakerOfClassWithConstructor().doSomething(someString);

        // This works
        PowerMockito.verifyNew(ClassWithConstructor.class).withArguments(
                someString);

        // This fails with error:
        // Wanted but not invoked:
        // classWithConstructor.doSomethingWithS(<any>);
        // -> at
        // com.example.constructortester.MakerOfClassWithConstructorTest.testSomething(MakerOfClassWithConstructorTest.java:30)
        // Actually, there were zero interactions with this mock.
        Mockito.verify(spyClassWithConstructor, times(1)).doSomethingWithS(
                someOtherString);
    }
}

2 个答案:

答案 0 :(得分:2)

这是一个Java错误。

尝试在测试启动器的VM参数中添加-noverify。 或者(最好的解决方案)更新JDK。我的版本是1.7.0_u67,我将其更新为版本1.7.0_u79并且工作正常(即使没有-noverify)。

答案 1 :(得分:0)

您必须在验证之前使用模拟对象调用该方法 所以你应该添加一行

spyClassWithConstructor.doSomethingWithS(someOtherString);

之前

 Mockito.verify(spyClassWithConstructor, times(1)).doSomethingWithS(
            someOtherString);

在你的情况下它不会验证(跳过它),因为你甚至没有调用方法,只有在调用方法后才能进行验证