Java Mockito 笔记
Mockito
1 Overview
2 Maven 项目初始化
3 示例
3.1 第一个示例
3.2 自动 Mock
3.3 Mock 返回值
3.4 Mock 参数
3.5 自动注入 Mock 对象
3.6 验证调用次数
3.7 预设 Exception
3.8 Void Mock
3.9 级联 Mock
3.10 部分 Mock
4 FAQ
4.1 注意点
5 References
pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
>4.0.0 >
>com.lld >
>test.mockito >
>0.0.1-SNAPSHOT >
>jar >
>test.mockito >
>http://maven.apache.org
>
>org.springframework.boot >
>spring-boot-starter-parent >
>1.5.4.RELEASE >
>
>
.build.sourceEncoding>UTF-8 .build.sourceEncoding>
>
>
>
>org.springframework.boot >
>spring-boot-starter >
>
>
>org.springframework.boot >
>spring-boot-starter-test >
>
>
>org.mockito >
>mockito-all >
>1.9.5 >
>test >
>
>
>
>
>
>org.springframework.boot >
>spring-boot-maven-plugin >
>
>
>
>
MainService.java
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class MainService {
@Autowired
OtherService otherService;
public void call() {
System.out.println("value is: " + otherService.getValue());
}
}
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class MainService {
@Autowired
OtherService otherService;
public void call() {
System.out.println("value is: " + otherService.getValue());
}
}
import org.springframework.stereotype.Component;
@Component
public class OtherService {
public String getValue() {
return "real value";
}
}
常规情况下,我们需要手工注入 Mock 对象,如下所示:
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = DemoConfig.class)
public class AutoInjectTest {
@Autowired
MainService service;
@Mock
OtherService otherService;
@Test
public void manualInjectTest() {
otherService = mock(OtherService.class);
when(otherService.getValue()).thenReturn("mock value");
service.setOtherService(otherService);
service.call();
}
}
PS:需要在 MainService 类中添加 setOtherService() 方法以允许修改 otherService
其中 DemoConfig 是配置类,对于 Spring Boot 框架,Test 类不会自动注入 Autowired 对象,需要使用 Config 类指定加载类,内容如下:
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Configuration
@ComponentScan({ "com.lld.test" })
public class DemoConfig {
}
但更合理的方式是使用 @InjectMocks 注解来自动注入,如下所示
import static org.mockito.Mockito.when;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = DemoConfig.class)
public class AutoInjectTest {
@Autowired
@InjectMocks
MainService service;
@Mock
OtherService otherService;
@Before
public void setup() {
MockitoAnnotations.initMocks(this);
when(otherService.getValue()).thenReturn("mock value");
}
@Test
public void autoInjectTest() {
service.call();
}
}
注意如下几点:
- 在 @Before 方法中初始化 Mock 对象及自动注入
- 在需要自动注入成员的类上添加 @InjectMocks 注解
另外值得注意的是,@InjectMocks 只会注入当前对象的成员,不会递归深度注入对象,例如,我们如果将 MainService 修改如下:
@Component
public class MainService {
@Autowired
MiddleService middleService;
public void callMiddle() {
System.out.println("value is: " + middleService.getValue());
}
}
添加 MiddleService 如下所示
@Component
public class MiddleService {
@Autowired
OtherService otherService;
public String getValue() {
return otherService.getValue();
}
}
这样的话,Unit Test 需要修改如下:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = DemoConfig.class)
public class AutoInjectTest {
@Autowired
MainService service;
@Mock
OtherService otherService;
@Autowired
@InjectMocks
MiddleService middleService;
@Before
public void setup() {
MockitoAnnotations.initMocks(this);
when(otherService.getValue()).thenReturn("mock value");
}
@Test
public void autoInjectDeepTest() {
service.callMiddle();
}
}
Mockito 1.x
Mockito 2.x
How to mock with Mockito