普通java项目
第一步:导入依赖的包
<dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <scope>test</scope> </dependency> <dependency> <groupId>org.mockito</groupId> <artifactId>mockito-all</artifactId> <version>1.9.0</version> <scope>test</scope> </dependency>
第二步:编写测试类
@RunWith(MockitoJUnitRunner.class)
Mockito是通过JUnit运行器运行的,它替我们创建所有必需的模拟对象,并将其注入包含测试的类。
要让一个类能够使用Mockito注解,必须使用MockitoJUnitRunner运行。
@RunWith(MockitoJUnitRunner.class)
public class MockitoTest{}
第三步:注入需要Mock的待测试对象
@InjectMocks
测试类中,需要使用@InjectMocks标注受测类,以告诉Mockito应将模拟对象注入哪个类
注意,Mockito会调用对象的无参构造方法创建后注入
@InjectMocks
UserService userService;
第四步:注入需要Mock的对象
@Mock
指定要将@InjectMocks标注的类中哪些方法或对象替换为模拟对象
第五步:Mock的demo
public class Student { private String name; public Student(String name) { this.name = name; } public String getName() { return name; } } public class StudentMapper { public Student getStudent(){ return null; } } public class StudentService { private StudentMapper studentMapper; public Student getStudent(){ return studentMapper.getStudent(); } } @RunWith(MockitoJUnitRunner.class) public class MockitoTest{ @InjectMocks StudentService studentService; @Mock StudentMapper studentMapper; @Test public void mockTest(){ Student stu = new Student("zwy"); doReturn(stu).when(studentMapper).getStudent(); System.out.println(studentMapper.getStudent()); System.out.println(studentService.getStudent()); } @Test public void spyTest(){ String exceptStuName = "yly"; Student stu = new Student("zwy"); // doReturn(exceptStuName).when(stu).getName();//异常 System.out.println(stu.getName()); Student spyStudent = spy(stu); doReturn(exceptStuName).when(spyStudent).getName();//正常 System.out.println(spyStudent.getName()); } }
结论
1.被 @InjectMocks 标注的对象不能直接mock而被 @Mock 标注的对象可以
2.被 spy(T) 方法包装后的对象可以mock他的行为
@Spy和@Mock的区别?
1.默认行为的不同
对于未指定mock的方法,spy默认会调用真实的方法,有返回值的返回真实的返回值,
而mock默认不执行,有返回值的,默认返回null
2.都不会自动装配到其他容器Bean
SpringBoot项目
说明:spring-boot-test模块中默认集成了mockito所以我们可以直接使用。
第一步:编写测试类
import org.junit.runner.RunWith; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.boot.test.mock.mockito.SpyBean; import org.springframework.test.context.junit4.SpringRunner; @SpringBootTest @RunWith(SpringRunner.class) public class ApplicationTest { @MockBean StudentMapper studentMapper; @SpyBean StudentService studentService; }
@SpyBean和@MockBean的区别?
1.默认行为不同
@MockBean属于替换容器的Bean,没有mock的行为返回null
@SpyBean监听容器Bean的行为,没有mock的行为调用Bean的真实方法
2.都会自动装配
通用
如何 Mock 对象的行为?
// mock返回对象
Mockito.when(methodCall).thenReturn(value)
Mockito.doReturn(toBeReturned).when(mock).[method]
// mock返回void
Mockito.doNothing().when(mock).[method]
// mock抛出异常
Mockito.doThrow(Exception.when(mock).[method]
如何匹配任何参数返回Mock的对象?
Mockito.anyInt()任何int值,Mockito.any(XXX.class)任何XXX类型的值
Mockito.any();
Mockito.any(Student.class);
Mockito.anyString();
如何根据参数的不同判断只有符合条件的参数返回mock的值?
argThat(ArgumentMatcher<T> matcher)
创建参数的Matcher
Matcher<String> argumentMatcher = new ArgumentMatcher<String>() {
@Override
public boolean matches(Object o) {
if("Joe".equals(o)){
return true;
}
return false;
}
};
Mockito.argThat(argumentMatcher);
如何根据参数的不同返回不同的值?
Mockito.doAnswer(new CustomAnswer()).when(mock).get(Mockito.anyInt());
public class CustomAnswer implements Answer<String> {
public String answer(InvocationOnMock invocation) throws Throwable {
Object[] args = invocation.getArguments();
Integer num = (Integer) args[0];
if (num > 3) {
return "大于三";
} else {
return "小于三";
}
}
}
官方文档
https://javadoc.io/doc/org.mockito/mockito-core/latest/org/mockito/Mockito.html