【问题标题】:Powermock: How to mock a private method inside a static classPowermock:如何在静态类中模拟私有方法
【发布时间】:2013-11-08 08:51:59
【问题描述】:

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

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()方法?

【问题讨论】:

    标签: java unit-testing mocking


    【解决方案1】:

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

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

    【讨论】:

    • 然后改变测试使其通过? Powermock 能够使用“间谍”模拟私有方法。只是我无法访问最终类中的私有方法。
    【解决方案2】:

    您可以使用java reflection 访问class 中的private 方法。如此类似的方式你可以测试这个private 方法。

    【讨论】:

      【解决方案3】:

      通常可以使用绕过封装技术来测试这种情况。这是一个例子:https://code.google.com/p/powermock/wiki/BypassEncapsulation。坦率地说,它只是通过使用 java 反射 API 来破解类隐私,所以你不必改变你的类结构来测试它。

      【讨论】:

      • @MiguelPortugal,不,我没有任何可信赖的近期文档。但我深入研究了源文件,似乎它们将类 WhiteBox 重命名为 WhiteBoxImpl,这与文章中描述的完全一样。
      【解决方案4】:

      这应该会有所帮助-> 在类上模拟私有静态方法

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

      这是我的课程代码。我也修改了你的 CUT。

      测试类:

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

      剪切: 公共最终类 NumberUtility{

      public static Integer getNumberPlusOne(Integer num){
      
      return doSomethingFancyInternally(num);} 
      
      private static Integer doSomethingFancyInternally(Integer num){
      
        //Fancy code here...
      
      return num;} 
      
      }
      

      【讨论】:

      • 无法创建 NumberUtility 的另一个实例,因为它是一个静态最终类。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-10-28
      • 1970-01-01
      • 2020-05-26
      • 2012-02-09
      • 1970-01-01
      • 2018-10-19
      • 1970-01-01
      相关资源
      最近更新 更多