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


98

我想从包含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"); 给出了我无法从http://code.google.com/p/powermock/wiki/MockitoUsage获得的无法提供嘲笑的编译器错误。

Answers:


135

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

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

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

javadoc

创建具有指定策略的类模拟,以解决交互问题。这是一个非常高级的功能,通常您不需要它来编写不错的测试。但是,在使用旧系统时可能会有所帮助。这是默认答案,因此仅当您不存根方法调用时才使用它。

默认默认磕碰的策略是只返回NULL,0或假的对象,数量和布尔值的方法。通过使用2-arg重载,您说的是:“不,不,不,默认情况下,使用此Answer子类的answer方法获取默认值。它返回Long,因此,如果您有静态方法返回的值与长期存在问题。

而是使用模拟静态的1-arg版本启用静态方法的存根,然后使用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 2014年

嗯...有点像这样。也许PowerMockito会为您重放PowerMock吗?我也对此感到奇怪。
djangofan,2015年

3
但是,如果我需要确保某些静态方法被精确的参数调用怎么办?
elTomato

6
@PrepareForTest注释应该是类调用静态方法,而不是类,其中静态方法。
Hazel Troost

5
@HazelTroost-不,OP是正确的。该类包含应为测试准备的静态方法。所以,@PrepareForTest(ClassWithStatics.class)对。
arry36 '19
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.