PowerMockito 模拟单个静态方法并返回对象

Posted

技术标签:

【中文标题】PowerMockito 模拟单个静态方法并返回对象【英文标题】:PowerMockito mock single static method and return object 【发布时间】:2012-05-21 22:18:58 【问题描述】:

我想从一个包含 2 个静态方法 m1 和 m2 的类中模拟一个静态方法 m1。我希望方法 m1 返回一个对象。

我尝试了以下

1)

PowerMockito.mockStatic(Static.class, new Answer<Long>() 
         @Override
         public Long answer(InvocationOnMock invocation) throws Throwable 
            return 1000l;
         
      );

这同时调用了 m1 和 m2,它们具有不同的返回类型,因此它给出了返回类型不匹配错误。

2) PowerMockito.when(Static.m1(param1, param2)).thenReturn(1000l); 但是在执行 m1 时不会调用它。

3) PowerMockito.mockPartial(Static.class, "m1"); 给出了 mockPartial 不可用的编译器错误,这是我从 http://code.google.com/p/powermock/wiki/MockitoUsage 得到的。

【问题讨论】:

【参考方案1】:

您想要做的是 1 的一部分和 2 的全部组合。

您需要使用 PowerMockito.mockStatic 为类的所有静态方法启用静态模拟。这意味着可以使用 when-thenReturn 语法对它们进行存根。

但是,您使用的 mockStatic 的 2 参数重载为 Mockito/PowerMock 在调用未在模拟实例上显式存根的方法时应该执行的操作提供了默认策略。

来自javadoc:

创建具有指定策略的类模拟,以获取其答案 互动。这是相当高级的功能,通常你不需要 它编写体面的测试。但是,在使用时可能会有所帮助 遗留系统。这是默认答案,因此仅在以下情况下使用 你不会存根方法调用。

默认默认存根策略是只为对象、数字和布尔值方法返回 null、0 或 false。通过使用 2-arg 重载,您是在说“不,不,不,默认情况下使用这个 Answer 子类的回答方法来获取默认值。它返回一个 Long,所以如果你有静态方法返回的东西不兼容长,有问题。

改为使用 1-arg 版本的 mockStatic 来启用静态方法的存根,然后使用 when-thenReturn 指定对特定方法执行的操作。例如:

import static org.mockito.Mockito.*;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;

class ClassWithStatics 
  public static String getString() 
    return "String";
  

  public static int getInt() 
    return 1;
  


@RunWith(PowerMockRunner.class)
@PrepareForTest(ClassWithStatics.class)
public class StubJustOneStatic 
  @Test
  public void test() 
    PowerMockito.mockStatic(ClassWithStatics.class);

    when(ClassWithStatics.getString()).thenReturn("Hello!");

    System.out.println("String: " + ClassWithStatics.getString());
    System.out.println("Int: " + ClassWithStatics.getInt());
  

String 值静态方法被存根返回“Hello!”,而 int 值静态方法使用默认存根,返回 0。

【讨论】:

不需要重播吗? 但是如果我需要确保使用精确的参数调用某个静态方法呢? @PrepareForTest注解应该是调用静态方法的类,而不是静态方法所在的类。 @HazelTroost - 不,OP 是对的。它是包含应该为测试准备的静态方法的类。所以,@PrepareForTest(ClassWithStatics.class) 是对的。 给我一个MissingMethodInvocationException

以上是关于PowerMockito 模拟单个静态方法并返回对象的主要内容,如果未能解决你的问题,请参考以下文章

使用PowerMockito和Mockito进行模拟测试,包括静态方法测试,私有方法测试等

使用PowerMockito 对静态类进行mock

使用静态方法使用PowerMockito时出现异常

如何使用powermockito,模拟一个类中的私有静态属性,而且这个属性是了工

PowerMockito 在 Spring Boot 中模拟私有方法

Spring启动在集成测试中使用PowerMock模拟静态方法