mockito 创建实例
Random rand = Mockito.mock(Random.class);
sout(rand.nextInt());
Mockito.verify(rand, Mockito.times(1)).nextInt(); // 写法奇怪,verify(对象,times).方法
如果不对于对象的行为不进行定义,那么方法的返回值总是 类型的默认值
需要打桩: when 方法
when(object.fun()).thenReturn(100); // 定义了对象的行为
如果不想每一次自己生成对象
可以使用@mock
注解,这个注解需要和openMocks一起用
@Mock
private Random rand;
@BeforeEach
void Setup() {
MockitoAnnotations.openMocks(this);
System.out.println("void fun is enough before");
}
Spy 和Mock的区别
// @Mock 的对象 默认不会调用真实的方法,直接返回类型的默认值
// @Spy 的对象 默认会调用方法
// 二者都可以被 打桩,改变默认行为
doReturn.when().add 和when().thenReturn的区别
是否会调用原方法—对于spy类型来说
多次thenReturn的规则
如果该序号已经定义,则返回定义的结果
否则返回最后一次的结果
例子
class MainTest {
@Spy
private Main dd;
// @Mock 的对象 默认不会调用真实的方法,直接返回类型的默认值
// @Spy 的对象 默认会调用方法,后面可以打桩,但是打桩when thenReturn的时候会调用 原来的实现
// 二者都可以被 打桩,改变默认行为
@BeforeEach
void Setup() {
MockitoAnnotations.openMocks(this);
System.out.println("void fun is enough before");
}
@org.junit.jupiter.api.Test
void add() {
Mockito.when(dd.add(1, 2)).thenReturn(4).thenReturn(5); // 这里会调用本体,本体只被调用一次
int aa1 = dd.add(1, 2); // 第一个then Return的结果
int bb2 = dd.add(1, 2); // 第二个then return 的结果
int bb3 = dd.add(1, 2); // 最后一个thenReturn的结果
int cc_diff = dd.add(2, 1); // 参数不对应,调用本体
System.out.println("aa1=" + aa1 + "\tbb2=" + bb2 + "\tbb3=" + bb3 + "\tcc=" + cc_diff
);
}
@org.junit.jupiter.api.Test
void add_doReturn_when() {
Mockito.doReturn(5).when(dd).add(1, 2); // 这里会调用本体,本体只被调用一次
int aa1 = dd.add(1, 2); // 第一个then Return的结果
int bb2 = dd.add(1, 2); // 第二个then return 的结果
int bb3 = dd.add(1, 2); // 最后一个thenReturn的结果
int cc_diff = 0; //dd.add(2, 1); // 参数不对应,调用本体
System.out.println("aa1=" + aa1 + "\tbb2=" + bb2 + "\tbb3=" + bb3 + "\tcc=" + cc_diff
);
}
}
参数是对象的时候
如果直接写我们传入的参数不方便,就用any。
不同的打桩方式
- thenReturn
- thenThrow
- thenCallRealMethod
静态方法的处理
要想搞静态方法,需要以来换成-inline
@Test
void testStaticName() { // 一般这个对象也要搞到setup方法里面
try (MockedStatic<Main> mainObj = Mockito.mockStatic(Main.class)) // MockedStatic 包装
{
mainObj.when(()->Main.range(1, 5)).thenReturn(Arrays.asList(10, 11, 12)); // 注意里面需要用 lambda表达式
mainObj.when(Main::getName).thenReturn("monica"); // 无参数的方法可以省略一点
} // try ()里面定义的变量会被释放
// MockedStatic 里面是threadlocal,
}//
为对象注入子对象
这里用到了注解:@InjectMocks
MockitoAnnotations.openMocks(this); //开启所有的mock
对于异常的校验
try {
// balabala 自己的逻辑
Assertions.fail("到这里就错了")
} catch (Exception e) {
Assertiions.assertTrue( e instanceof Exception); // instance of
}
中间调用了别的东西
直接把别的东西,而且别的东西不可控, when thenReturn掉
如果中间调用的东西是可控的,那么callRealMethod
基本流程
- 如果测试对象 spy
- 如果是对象依赖的东西 mock 和InjectMocks
- setup openmocks
- 准备条件: 能控制的callRealMethod,不能控制的直接thenReturn
- 执行
- assert
依赖
<dependencies>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>4.3.1</version>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>5.8.2</version>
</dependency>
</dependencies>
快速创建测试类
generate里面、alt+enter
mavin 包没有生效怎么办
在POM文件右键,maven- > reload
怎样跑一个测试用例