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

简介: 本文将简单介绍如何使用PowerMock和Mockito来mock1. 构造函数2. 静态函数3. 枚举实现的单例4. 选择参数值做为函数的返回值5. 在调用mock出来的方法中,改变方法参数的值一点简要说明:Mockito其实已经可以满足大部分的需求,但是它的实现机制是使用cglib来动态创建接口的类的实例。

本文将简单介绍如何使用PowerMock和Mockito来mock
1. 构造函数
2. 静态函数
3. 枚举实现的单例
4. 选择参数值做为函数的返回值
5. 在调用mock出来的方法中,改变方法参数的值

一点简要说明: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);//mock静态字段时,也可以使用此方法
          
      // 调用需要测试方法
      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)

 

5. 在调用mock出来的方法中,改变方法参数的值
when( myMock.someMethod( any( List.class ) ) ).thenAnswer( ( new Answer<Void>() {
    @Override
    public Void answer( InvocationOnMock invocation )
            throws Throwable {
        Object[] args = invocation.getArguments();
        List arg1 = (List)args[0];
        arg1.add("12345");
        return null;
    }
} ) );



Verifying with generic parameters
verify(someService).process(Matchers.<Collection<Person>>any());
verify(adunoMasterBaseProcessor).processBinFiles( anyListOf(File.class) );
http://www.blogjava.net/usherlight/archive/2015/06/16/425740.html

 

相关文章
|
前端开发 网络协议 Dubbo
超详细Netty入门,看这篇就够了!
本文主要讲述Netty框架的一些特性以及重要组件,希望看完之后能对Netty框架有一个比较直观的感受,希望能帮助读者快速入门Netty,减少一些弯路。
90892 32
超详细Netty入门,看这篇就够了!
|
2月前
|
算法 API 开发者
沪深A股实时行情API接入指南
逐笔Tick数据接口,查询A股上市公司的最新成交明细,确保获取市场的最新交易信息。返回示例如下:
|
人工智能 Java 测试技术
JDK11下Mock框架进化:从PowerMockito到Mockito Only
本文探讨了从使用PowerMock的测试环境迁移到仅使用Mockito(Mockito Only)策略的必要性和实践方法。
402 10
|
IDE Java 测试技术
单元测试问题之Mockito 3.4mock静态方法如何解决
单元测试问题之Mockito 3.4mock静态方法如何解决
774 1
|
Go Java
mockito中两种部分mock的实现,spy、callRealMethod
什么是类的部分mock(partial mock)?A:部分mock是说一个类的方法有些是实际调用,有些是使用mockito的stubbing(桩实现)。   为什么需要部分mock? A:当需要测试一个组合方法(一个方法需要其它多个方法协作)的时候,某个叶子方法(只供别人调用,自己不依赖其它反复)已经被测试过,我们其实不需要再次测试这个叶子方法,so,让叶子打桩实现返回结果,上层方法实际调用并测试。
4635 1
|
设计模式 Java 数据库
【设计模式】JAVA Design Patterns——Converter(转换器模式)
转换器模式旨在实现不同类型间的双向转换,减少样板代码。它通过通用的Converter类和特定的转换器(如UserConverter)简化实例映射。Converter类包含两个Function对象,用于不同类型的转换,同时提供列表转换方法。当需要在逻辑上对应的类型间转换,或处理DTO、DO时,此模式尤为适用。
【设计模式】JAVA Design Patterns——Converter(转换器模式)
|
Java API Spring
Spring Boot中配置Swagger用于API文档
Spring Boot中配置Swagger用于API文档
|
网络协议 网络架构
计算机网络中MSS和MTU的区别
【4月更文挑战第11天】
1534 0
计算机网络中MSS和MTU的区别
|
XML Java 程序员
保姆级教程,手把手教你实现SpringBoot自定义starter
保姆级教程,手把手教你实现SpringBoot自定义starter
12766 2
保姆级教程,手把手教你实现SpringBoot自定义starter
|
消息中间件 存储 安全