简体   繁体   English

Powermock:如何在静态类中模拟私有方法

[英]Powermock: How to mock a private method inside a static class

Let's say that I have a utility class like this: 假设我有一个如下的实用程序类:

public final class NumberUtility{

public static int getNumberPlusOne(int num){

   return doSomethingFancyInternally(num);

}

private static int doSomethingFancyInternally(int num){

      //Fancy code here...

  return num;

}

}

Assuming that I don't change the class's structure, how do mock the doSomethingFancyInternally() method with the use of Powermock? 假设我不更改类的结构,如何使用Powermock模拟doSomethingFancyInternally()方法?

Why you cannot mock getNumberPlusOne method with PowerMock ? 为什么不能使用PowerMock模拟getNumberPlusOne方法? Private method shouldn't be visible in tests. 私有方法不应在测试中可见。

For example someone change internal implementation of private method ( change method name even) then your test will fail. 例如,有人更改了私有方法的内部实现(甚至更改了方法名称),则测试将失败。

you can use java reflection to access private method in a class . 您可以使用java reflection来访问class private方法。 So similar way you can test this private method. 所以类似的方式,您可以测试此private方法。

Usually to test such a situations the Bypass encapsulation technique can be used. 通常为了测试这种情况,可以使用旁路封装技术。 Here is the example of this: https://code.google.com/p/powermock/wiki/BypassEncapsulation . 这是一个示例: https : //code.google.com/p/powermock/wiki/BypassEncapsulation Frankly speaking it just hacks the class privacy with use of the java reflection API, so you're not forced to change your class strcuture to test it. 坦白地说,它只是使用java反射API来破坏类的隐私,因此您不必更改类结构即可对其进行测试。

This should help-> Mocking a private static method on a class 这应该有助于->在类上模拟私有静态方法

http://avricot.com/blog/index.php?post/2011/01/25/powermock-%3A-mocking-a-private-static-method-on-a-class http://avricot.com/blog/index.php?post/2011/01/25/powermock-%3A-mocking-a-private-static-method-on-a-class

Here's my code for your class. 这是我上课的代码。 I modified your CUT too. 我也修改了您的CUT。

TEST CLASS: 测试类别:

import org.easymock.EasyMock;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.api.easymock.PowerMock;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;

@RunWith(PowerMockRunner.class)    
@PrepareForTest({ NumberUtility.class })
public class NumberUtilityTest {

// Class Under Test
NumberUtility cut;

@Before
public void setUp() {

    // Create a new instance of the service under test (SUT).
    cut = new NumberUtility();

    // Common Setup
    // TODO
}

/**
 * Partial mocking of a private method.
 * 
 * @throws Exception
 * 
 */
@Test
public void testGetNumberPlusOne1() throws Exception {

    /* Initialization */
    PowerMock.mockStaticPartial(NumberUtility.class,
            "doSomethingFancyInternally");
    NumberUtility partialMockCUT = PowerMock.createPartialMock(
            NumberUtility.class, "doSomethingFancyInternally");
    Integer doSomethingFancyInternallyOutput = 1;
    Integer input = 0;

    /* Mock Setup */
    PowerMock
            .expectPrivate(partialMockCUT, "doSomethingFancyInternally",
                    EasyMock.isA(Integer.class))
            .andReturn(doSomethingFancyInternallyOutput).anyTimes();

    /* Activate the Mocks */
    PowerMock.replayAll();

    /* Test Method */
    Integer result = NumberUtility.getNumberPlusOne(input);

    /* Asserts */
    Assert.assertEquals(doSomethingFancyInternallyOutput, result);
    PowerMock.verifyAll();

}

}

CUT: public final class NumberUtility{ 剪切:公共最终课程NumberUtility {

public static Integer getNumberPlusOne(Integer num){

return doSomethingFancyInternally(num);} 

private static Integer doSomethingFancyInternally(Integer num){

  //Fancy code here...

return num;} 

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM