TestNG + Mockito + PowerMock - verifyStatic()不起作用 [英] TestNG + Mockito + PowerMock - verifyStatic() does not work

查看:1230
本文介绍了TestNG + Mockito + PowerMock - verifyStatic()不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am new TestNG and unit-testing in general. I am using TestNG 6.9.6 with Mockito 1.10.19 and PowerMock 1.6.4. I want to verify whether the myMethod() method in MyService class internally calls the static method Util.myStaticMethod with the correct arguments. Since verification of static methods is not natively supported in Mockito, I am using PowerMock along with it. My Test class is shown below:

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

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

This test is expected to fail, as myMethod calls the static method Util.myStaticMethod() only once. But when i run the test, it always passes, no matter what value i pass to PowerMockito.verifyStatic().

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

Also, if I write another test method in this class and then run the test, I get the following error

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

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

It fails at the verifyStatic() method, which makes me think that the verifyStatic() method needs something more that i am not providing. Also, it indicates the total number of tests as 3 whereas in this case I have only two test methods.

任何帮助都将不胜感激。

Any help would be appreciated.

编辑:根据建议,我尝试在 @PrepareForTest <中添加 MyUtil 类/ code>注释,它仍然会给出相同的错误。

EDIT : As suggested, I tried putting MyUtil class in the the @PrepareForTest annotation, it still gives the same error.

推荐答案

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

OK, I think this is very specific to TestNG configurations, since all of the JUnit examples work 'out of the box'!

通读这个来自PowerMock GitHub站点的链接,该站点详细描述了如何将TestNG与PowerMock一起使用。使用以下示例代码描述了验证模拟 static 方法的调用的确切方案:

Read through this link from the PowerMock GitHub site which describes further detail on how to use TestNG together with PowerMock. Exactly your scenario of verifying calls to mocked static methods is described there using this example code:


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

}


然后是这一小块信息:


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

For this to work you need to tell TestNG to use the PowerMock object factory

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

This is done using either TestNG XML config, or in the test's code itself. For completeness I've copied below the options given at the above URL. FWIW I extended PowerMockTestCase and the verification worked as you expect.

最后,不要忘记 @PrepareForTest 正确的类 - 即包含<* c $ c> static 方法的类,你想要模拟,因为@Bax指出这里

Finally, don't forget to @PrepareForTest the correct class - i.e. the class containing the static methods which you want to mock, as @Bax pointed out here.

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

As a further hint (which you probably already know about, but worth mentioning here anyway) since you aren't using Mockito to mock objects, MockitoAnnotations.initMocks(this) can be safely deleted.

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

Once you've got all this working, you might also like to consider whether the use of 'Black Magic' tools like Powermock is actually exposing code smells in your design? Especially since it looks like the classes containing static methods are under your ownership. This means you could use an alternative design that doesn't use statics. I highly recommend Michael Feathers' book Working Effectively with Legacy Code, it might just change your whole approach to software design and testing...

祝你好运!


< h1>配置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> 

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

If you're using Maven you may need to point out the file to Surefire:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-surefire-plugin</artifactId>
    <configuration>
        <suiteXmlFiles>
        <suiteXmlFile>suite.xml</suiteXmlFile>
        </suiteXmlFiles>
    </configuration> 
</plugin> 



以编程方式



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

Programmatically

Add a method like this to your test class:

@ObjectFactory public IObjectFactory getObjectFactory() {
     return new org.powermock.modules.testng.PowerMockObjectFactory(); 
} 

或为安全起见,您也可以从<$ c延伸$ c> PowerMockTestCase :

or to be on the safe side you can also extend from the PowerMockTestCase:

@PrepareForTest(IdGenerator.class) 
public class MyTestClass extends PowerMockTestCase { ... }


这篇关于TestNG + Mockito + PowerMock - verifyStatic()不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆