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

120

我想模拟一个包含两个静态方法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个回答

163

你想做的是1部分和2部分的组合。

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

但是,你正在使用mockStatic的两个参数重载版本,该版本为Mockito/PowerMock在你调用未明确存根的模拟实例上的方法时提供了默认策略。

javadoc中得知:

创建具有特定答案交互策略的类模拟。这是相当高级的功能,通常不需要编写良好的测试。但是,在处理旧系统时可能会有所帮助。这是默认答案,因此仅在未存根方法调用时才会使用它。

默认的桩造策略是对于返回对象、数字和布尔值方法,只返回null、0或false。使用2个参数的重载,您在说“不,不,不,使用这个Answer子类的answer方法来获取默认值。”它返回一个Long,如果您有返回与Long不兼容的内容的静态方法,则会出现问题。
相反,使用mockStatic的1个参数版本启用静态方法的桩造,然后使用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());
  }
}

字符串类型的静态方法被桩化为返回"Hello!",而整型类型的静态方法使用默认的桩化,返回0。

1
是否不需要回复? - Balaji Boggaram Ramanarayan
3
如果我需要确保某个静态方法被调用时具有精确的参数,该怎么办? - elTomato
11
@PrepareForTest 注解应该放在调用静态方法的类上,而不是包含静态方法的类上。 - Hazel T
12
@HazelTroost - 不,原帖是正确的。应该为包含静态方法的类准备测试。因此,@PrepareForTest(ClassWithStatics.class) 是正确的。 - arry36
3
出现了“MissingMethodInvocationException”异常。 - Akshay Hazari
显示剩余8条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接