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

时间:2013-11-08 08:52:00

标签: java unit-testing mocking

假设我有一个像这样的实用程序类:

public final class NumberUtility{

public static int getNumberPlusOne(int num){

   return doSomethingFancyInternally(num);

}

private static int doSomethingFancyInternally(int num){

      //Fancy code here...

  return num;

}

}

假设我没有更改类的结构,如何使用Powermock模拟doSomethingFancyInternally()方法?

4 个答案:

答案 0 :(得分:0)

为什么你不能用PowerMock模拟getNumberPlusOne方法? 私有方法不应在测试中可见。

例如,有人更改私有方法的内部实现(甚至更改方法名称),那么您的测试将失败。

答案 1 :(得分:0)

您可以使用java reflection访问private中的class方法。您可以通过类似的方式测试此private方法。

答案 2 :(得分:0)

通常为了测试这种情况,可以使用Bypass封装技术。以下是此示例:https://code.google.com/p/powermock/wiki/BypassEncapsulation。坦率地说,它只是通过使用java反射API来破解类隐私,所以你不必强迫改变你的类strcuture来测试它。

答案 3 :(得分:0)

这应该有帮助 - >在类

上模拟私有静态方法

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

这是我班级的代码。我也修改了你的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:     公共最终类NumberUtility {

public static Integer getNumberPlusOne(Integer num){

return doSomethingFancyInternally(num);} 

private static Integer doSomethingFancyInternally(Integer num){

  //Fancy code here...

return num;} 

}