TestNG + Mockito + PowerMock - verifyStatic()不起作用

Pan*_*ani 2 java testng unit-testing mockito powermock

我是新的TestNG和一般的单元测试.我使用的是TestNG 6.9.6和Mockito 1.10.19以及PowerMock 1.6.4.我想验证类中的myMethod()方法是否在MyService内部Util.myStaticMethod使用正确的参数调用静态方法.由于Mockito本身不支持静态方法的验证,因此我使用PowerMock.我的测试类如下所示:

public class MyTest
{
    private MyService myService;

    @Captor ArgumentCaptor<String> argCaptor;

    @BeforeMethod
    public void setup()
    {
        MockitoAnnotations.initMocks( this );
        myService = new MyService();
    }

    @Test
    @PrepareForTest(MyService.class)
    public void myTest()
    {
        PowerMockito.mockStatic(Util.class);
        myService.myMethod("arg");

        PowerMockito.verifyStatic(10);
        Util.myStaticMethod(anyString());
    }
}
Run Code Online (Sandbox Code Playgroud)

预计此测试将失败,因为仅myMethod调用静态方法Util.myStaticMethod()一次.但是当我运行测试时,无论我传递给什么价值,它总是会通过PowerMockito.verifyStatic().

另外,如果我在这个类中编写另一个测试方法然后运行测试,我会收到以下错误

org.mockito.exceptions.misusing.UnfinishedVerificationException: 
Missing method call for verify(mock) here:
-> at mypackage.MyTest.myTest(MyTest.java:21)

Example of correct verification:
    verify(mock).doSomething()

Also, this error might show up because you verify either of: final/private/equals()/hashCode() methods.
Those methods *cannot* be stubbed/verified.
Mocking methods declared on non-public parent classes is not supported.

    at mypackage.MyTest.myTest.setup(MyTest.java:10)


Results :

Failed tests: 
  MyTest.setup:10 UnfinishedVerification 
Missing method call for ver...

Tests run: 3, Failures: 1, Errors: 0, Skipped: 1
Run Code Online (Sandbox Code Playgroud)

它在verifyStatic()方法中失败,这使我认为verifyStatic()方法需要更多我不提供的东西.此外,它表示测试总数为3,而在这种情况下,我只有两种测试方法.

任何帮助,将不胜感激.

编辑:正如所建议的,我尝试将MyUtil类放在@PrepareForTest注释中,它仍然会给出相同的错误.

Ste*_*ley 7

好吧,我认为这是针对TestNG配置非常具体的,因为所有JUnit示例都可以"开箱即用"!

从PowerMock GitHub站点阅读链接,该站点详细描述了如何将TestNG与PowerMock一起使用.static使用此示例代码可以确切地描述验证对模拟方法的调用的情况:

@PrepareForTest(IdGenerator.class)
public class MyTestClass {

   @Test
   public void demoStaticMethodMocking() throws Exception {
      mockStatic(IdGenerator.class);
      when(IdGenerator.generateNewId()).thenReturn(2L);       
      new ClassUnderTest().methodToTest();

      // Optionally verify that the static method was actually called
      verifyStatic();
      IdGenerator.generateNewId();
   }

}
Run Code Online (Sandbox Code Playgroud)

然后是这一小块信息:

为此,您需要告诉TestNG使用PowerMock对象工厂

这是使用TestNG XML配置或测试代码本身完成的.为了完整起见,我复制了上面URL中给出的选项.FWIW我扩展PowerMockTestCase了,验证按预期工作.

最后,不要忘记@PrepareForTest正确的类 - 即包含static你想要模拟的方法的类,正如@Bax在这里指出的那样.

作为进一步的提示(你可能已经知道,但无论如何值得一提)因为你没有使用Mockito来模拟对象,MockitoAnnotations.initMocks(this)所以可以安全删除.

一旦你完成了所有这些工作,你可能还想考虑使用像Powermock这样的'Black Magic'工具是否真的暴露了设计中的代码味道?特别是因为看起来包含static方法的类属于您的所有权.这意味着您可以使用不使用statics 的替代设计.我强烈推荐Michael Feathers的书"有效地使用遗留代码",它可能只是改变了你对软件设计和测试的整个方法......

祝好运!

配置TestNG以使用PowerMock对象工厂

使用suite.xml

在suite.xml中,在套件标记中添加以下内容: object-factory="org.powermock.modules.testng.PowerMockObjectFactory"例如

<suite name="dgf" verbose="10"
    object-factory="org.powermock.modules.testng.PowerMockObjectFactory">
    <test name="dgf">
        <classes>
            <class name="com.mycompany.Test1"/>
            <class name="com.mycompany.Test2"/>
        </classes>
    </test> 
Run Code Online (Sandbox Code Playgroud)

如果你正在使用Maven,你可能需要将文件指向Surefire:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-surefire-plugin</artifactId>
    <configuration>
        <suiteXmlFiles>
        <suiteXmlFile>suite.xml</suiteXmlFile>
        </suiteXmlFiles>
    </configuration> 
</plugin> 
Run Code Online (Sandbox Code Playgroud)

编程

将这样的方法添加到您的测试类:

@ObjectFactory public IObjectFactory getObjectFactory() {
     return new org.powermock.modules.testng.PowerMockObjectFactory(); 
} 
Run Code Online (Sandbox Code Playgroud)

或者为了安全起见,您还可以从以下地址延伸PowerMockTestCase:

@PrepareForTest(IdGenerator.class) 
public class MyTestClass extends PowerMockTestCase { ... }
Run Code Online (Sandbox Code Playgroud)