IT博客汇
  • 首页
  • 精华
  • 技术
  • 设计
  • 资讯
  • 扯淡
  • 权利声明
  • 登录 注册

    简单介绍如何使用PowerMock和Mockito来mock 1. 构造函数 2. 静态函数 3. 枚举实现的单例 4. 选择参数值做为函数的返回值

    云自无心水自闲发表于 2015-06-16 13:27:00
    love 0
    本文将简单介绍如何使用PowerMock和Mockito来mock
    1. 构造函数
    2. 静态函数
    3. 枚举实现的单例
    4. 选择参数值做为函数的返回值

    一点简要说明:Mockito其实已经可以满足大部分的需求,但是它的实现机制是使用cglib来动态创建接口的类的实例。但是这种实现方式不能用于构造函数和静态函数,因为那需要使用类的字节码(比如使用javassist). 所以我们才需要结合使用PowerMock.

    1. mock构造函数, 如果有代码没有使用DI注入依赖实例,在单元测试中可以使用PowerMock来模拟创建对象。
    注意的开始两行的2个注解 @RunWith 和 @PrepareForTest
    @RunWith比较简单,后面始终是PowerMockRunner.class
    @PrepareForText后面需要加的是调用构造函数的类名,而不是有构造函数的类本身。
    在下面的例子中,我们要测试的类是:Helper, 在Helper类中调用了Somthing类的构造函数来创建实例。
    @RunWith(PowerMockRunner.class)
    @PrepareForTest(Helper.
    class)
    public class HelperTest {
    @Mock
    private Something mockSomething;

    @InjectMocks
    private Helper helper;

    @Test
    public void doSomething() throws Exception {
    String argument
    = "arg";

    PowerMockito.whenNew(Something.
    class).withArguments(argument).thenReturn(mockSomething);

    // 调用需要测试方法
    helper.doSomething(argument);

    // 进行验证
    verify(mockSomething).doIt();
    }
    }


    public class Helper {
    public void doSomething(String arg) {
    Something something = new Something(arg);
    something.doit();
    }
    }


    2,mock 静态函数, 单例模式就是一个典型的会调用静态函数的例子。 注意要点与mock构造函数相同。
    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());
    }
    }

    3。mock枚举实现的单例
    SingletonObject.java
    public enum SingletonObject {     
    INSTANCE
    ;
    private
    int num;

    protected
    void setNum(int num) {
    this.num = num;
    }

    public int getNum() {
    return
    num;
    }

    }

    SingletonConsumer.java

    public class SingletonConsumer {
        public String consumeSingletonObject() { 
    return
    String.valueOf(SingletonObject.INSTANCE.getNum());
    }
    }



    SingletonConsumerTest.java
    @RunWith(PowerMockRunner.class) 
    @PrepareForTest({SingletonObject.class})
    public class SingletonConsumerTest {
    @Test public void testConsumeSingletonObject() throws Exception {
    SingletonObject
    mockInstance = mock(SingletonObject.class);
    Whitebox
    .setInternalState(SingletonObject.class, "INSTANCE", mockInstance);

    when
    (mockInstance.getNum()).thenReturn(42);
    assertEquals
    ("42", new SingletonConsumer().consumeSingletonObject());
    }
    }
    4。返回参数值做为函数返回值。
    mockito 1.9.5之后,提供一个方便的方法来实现这个需要,在这之前可以使用一个匿名函数来返回一个answer来实现。
    when(myMock.myFunction(anyString())).then(returnsFirstArg());
    其中returnsFirstArg()是org.mockito.AdditionalAnswers中的一个静态方法。
    在这个类中还有其他的一些类似方法
    returnsSecondArg()
    returnsLastArg()
    ReturnsArgumentAt(int position)



    云自无心水自闲 2015-06-16 21:27 发表评论


沪ICP备19023445号-2号
友情链接