Mockito 是一个模拟测试框架,主要功能是在单元测试中模拟类/对象的行为。
单元测试 – Mockito设置方法返回值
1、thenReturn与doReturn
thenReturn 用来指定特定函数和参数调用的返回值。
thenReturn 中可以指定多个返回值。在调用时返回值依次出现。若调用次数超过返回值的数量,再次调用时返回最后一个返回值。
doReturn 的作用和thenReturn
相同,但使用方式不同(doReturn(1).when(random).nextInt();)
@RunWith(MockitoJUnitRunner.class)
public class Mocktio {
@Mock
private ExampleService exampleService;
@Test
public void test_spy() {
MockitoAnnotations.openMocks(this);
when(exampleService.add(anyInt(), anyInt())).thenReturn(1, 2, 3);
Assert.assertEquals(1, exampleService.add(1, 2));
Assert.assertEquals(2, exampleService.add(9, 7));
Assert.assertEquals(3, exampleService.add(10, 12));
Assert.assertEquals(3, exampleService.add(11, 6));
Assert.assertEquals(3, exampleService.add(7, 3));
}
class ExampleService {
int add(int a, int b) {
System.out.println("方法调用被执行");
return a+b;
}
}
}
2、thenThrow与doThrow
thenThrow用来让函数调用抛出异常。thenThrow 中可以指定多个异常。在调用时异常依次出现。若调用次数超过异常的数量,再次调用时抛出最后一个异常。
对应返回类型是 void 的函数,thenThrow
是无效的,要使用doThrow
。doThrow(new RuntimeException(“异常”)).when(exampleService).hello();
@RunWith(MockitoJUnitRunner.class)
public class Mocktio {
@Mock
private ExampleService exampleService;
@Test
public void test_spy() {
MockitoAnnotations.openMocks(this);
when(exampleService.add(anyInt(),anyInt())).thenThrow(new RuntimeException("异常"));
try {
exampleService.add(1, 2);
Assert.fail(); // 上面会抛出异常,所以不会走到这里
} catch (Exception ex) {
Assert.assertTrue(ex instanceof RuntimeException);
Assert.assertEquals("异常", ex.getMessage());
}
doThrow(new RuntimeException("异常")).when(exampleService).addPrint(1, 2);
try {
exampleService.addPrint(1, 2);
Assert.fail(); // 上面会抛出异常,所以不会走到这里
} catch (Exception ex) {
Assert.assertTrue(ex instanceof RuntimeException);
Assert.assertEquals("异常", ex.getMessage());
}
}
class ExampleService {
int add(int a, int b) {
System.out.println("方法调用被执行");
return a+b;
}
void addPrint(int a, int b) {
System.out.println("方法调用被执行");
}
}
}
3、thenAnswer
then 和 thenAnswer 的效果是一样的。它们的参数是实现 Answer 接口的对象,在改对象中可以获取调用参数,自定义返回值。
我们在对Mybatisinsert生成自增主键时的情况可以使用
Mockito.when(areaService.insert(any())).thenAnswer((Answer<Integer>) invocation -> {
Object[] args = invocation.getArguments();
// 获取参数
AreaEntity areaEntity = (AreaEntity) args[0];
areaEntity.setId(1);
return 1;
});
when(…)thenAnswer(…)的作用有以下三种
1、他可以返回一个值也可以抛出异常
2、他可以获取到传入的参数
3、他可以对参数进行判断,决定下一步动作
@Test
public void testThenAnswer() {
List mockedList = mock(List.class);
when(mockedList.size()).thenReturn(20);
when(mockedList.get(anyInt())).thenAnswer((Answer<String>) invocation -> {
Object[] args = invocation.getArguments();
In
teger index = (Integer) args[0];
if (index == 0) {
return "foo";
} else if (index == 1) {
return "bar";
} else if (index < 10) {
return "baz";
} else if (index < 20) {
return "qux";
} else {
throw new IndexOutOfBoundsException();
}
});
Assert.assertEquals(20, mockedList.size());
Assert.assertEquals("foo", mockedList.get(0));
Assert.assertEquals("bar", mockedList.get(1));
Assert.assertEquals("baz", mockedList.get(8));
Assert.assertEquals("qux", mockedList.get(16));
thrown.expect(IndexOutOfBoundsException.class);
mockedList.get(20);
}