本文将简单介绍如何使用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

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

  1. php7函数,声明,返回值等新特性介绍

    使用 ... 运算符定义变长参数函数 (PHP 5 >= 5.6.0, PHP 7) 现在可以不依赖 func_get_args(), 使用 ... 运算符 来实现 变长参数函数. functi ...

  2. LevelDb简单介绍和原理——本质:类似nedb,插入数据文件不断增长(快照),再通过删除老数据做更新

    转自:http://www.cnblogs.com/haippy/archive/2011/12/04/2276064.html 有时间再好好看下整个文章! 说起LevelDb也许您不清楚,但是如果作 ...

  3. java单元测试小结

    1. mock 构造函数 import static org.junit.Assert.*; import java.util.ArrayList; import org.junit.Test; im ...

  4. OpenCV 编程简单介绍(矩阵/图像/视频的基本读写操作)

    PS. 因为csdn博客文章长度有限制,本文有部分内容被截掉了.在OpenCV中文站点的wiki上有可读性更好.而且是完整的版本号,欢迎浏览. OpenCV Wiki :<OpenCV 编程简单 ...

  5. 从头认识Spring-1.14 SpEl表达式(1)-简单介绍与嵌入值

    这一章节我们来讨论一下SpEl表达式的简单介绍与嵌入值. 1.SpEl表达式简单介绍 Spring Excpression Language (SpEL)语言支持在执行时操作和查询对象 事实上就是在执 ...

  6. SQLite简单介绍

    一.离线缓存 在项目开发中,通常都需要对数据进行离线缓存的处理,如新闻数据的离线缓存等. 说明:离线缓存一般都是把数据保存到项目的沙盒中.有以下几种方式 (1)归档:NSCodeing.NSKeyed ...

  7. LuaInterface简单介绍

    LuaInterface简单介绍 Lua是一种非常好的扩展性语言.Lua解释器被设计成一个非常easy嵌入到宿主程序的库.LuaInterface则用于实现Lua和CLR的混合编程. (一)Lua f ...

  8. 《PHP 5.5从零開始学(视频教学版)》内容简单介绍、文件夹

    <PHP 5.5从零開始学(视频教学版)>当当网购买地址: http://product.dangdang.com/23586810.html <PHP 5.5从零開始学(视频教学版 ...

  9. 对JavaScript事件处理程序/事件监听器的设定的简单介绍

    下面是一些对事件处理进行设定的方式. 指定为HTML元素的属性(事件处理程序) 指定为DOM元素的属性(事件处理程序) 通过EventTarget.addEventListener()进行指定(事件监 ...

随机推荐

  1. Kdd Cup 2013 总结2

  2. mongoDB 批量更改数据,某个字段值等于另一个字段值

    由于mongodb数据库类似js的写法,所以即使数据库中新的列不存在也会自动创建 db.hospital.find().forEach( function(item){ db.hospital.upd ...

  3. Hadoop单机版安装,配置,运行

    Hadoop是最近非常流行的东东啦,但是乍一看都觉得是集群的东东,其实在单机版上安装Hadoop也是可以的,并且安装好以后可以很方便的进行程序的调试,调试好程序以后再丢到集群中,放心的算吧,呵呵.. ...

  4. HDU 4643 GSM 暑期多校联合训练第五场 1001

    点击打开链接 我就不说官方题解有多坑了 V图那么高端的玩意儿 被精度坑粗翔了 AC前 AC后 简直不敢相信 只能怪自己没注意题目For the distance d1 and d2, if fabs( ...

  5. Oracle历史记录

    请问如何查询ORACLE的历史操作记录!!!!!------解决方案-------------------- 有一个专门存储操作的数据库表..select t.SQL_TEXT, t.FIRST_LO ...

  6. ecshop 浏览历史样式的修改

    ecshop的浏览历史的样式,例如我修改的是只让浏览历史显示浏览历史的商品名称 而不显示浏览历史的商品的价格和图片 首先找到要修改 的文件includes\lib_insert.php 找到函数fun ...

  7. 一个css和js结合的下拉菜单,支持主流浏览器

    首先声明: 本人尽管在web前端岗位干了好多年,但无奈岗位对技术要求不高.html,css用的比較多,JavaScript自己原创的非常少,基本都是copy改动,所以自己真正动手写时,发现基础非常不坚 ...

  8. 你不知道的Eclipse的用法:使用MAT分析Android的内存

    如果使用DDMS确实发现了我们程序中存在内存泄露,那如何定位到具体出现问题的代码片段,最终找到问题所在呢?如果从头到尾分析代码逻辑,那肯定会把人逼疯,特别是在维护别人写的代码的时候.这里介绍一个极好的 ...

  9. 无法打开登录所请求的数据库 "ASPState"。登录失败。 用户 'NT AUTHORITY/SYSTEM' 登录失败。

    原文:无法打开登录所请求的数据库 "ASPState".登录失败. 用户 'NT AUTHORITY/SYSTEM' 登录失败. 无法打开登录 'ASPState' 中请求的数据库 ...

  10. 实现strcmp非常easy的思维

    #define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<stdlib.h> void strcom(char *s ...