SpringBoot+Mockito的简单使用
引入依赖
<dependency><groupId>org.mockito</groupId><artifactId>mockito-all</artifactId><version>1.10.19</version><scope>test</scope></dependency>
被测试类
package com.crud.bussiness;import com.crud.Enum.Name;import com.crud.entity.Blog;import com.crud.service.impl.BlogServiceImpl;import com.crud.service.impl.UserServiceImpl;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Component;import javax.annotation.Resource;import java.util.List;@ComponentpublicclassUserAndBlog{@Autowiredprivate UserServiceImpl userServiceImpl;@Autowiredprivate BlogServiceImpl blogServiceImpl;public List<Blog>getBlogByName(String name){
Name someone=Name.markerhub;if(name.equals(someone.toString())){int user_id= userServiceImpl.getUserIdByUserName(name);return blogServiceImpl.getBlogByUserId(user_id);}else{return blogServiceImpl.getBlogByUserId(5);}}}
@Mock简单测试
package com.crud.bussiness;import com.crud.entity.Blog;import org.mockito.Mock;import org.mockito.MockitoAnnotations;import org.springframework.boot.test.context.SpringBootTest;import org.testng.annotations.BeforeClass;import org.testng.annotations.Test;import java.util.ArrayList;import java.util.List;importstatic org.mockito.ArgumentMatchers.anyString;importstatic org.mockito.Mockito.when;@SpringBootTestpublicclassUserAndBlogMockBeanTest{@Mockprivate UserAndBlog userAndBlog;@BeforeClasspublicvoidinitMocks()throws Exception{
System.out.println("Before Class");//MockitoAnnotations.initMocks(this),其中this就是单元测试所在的类,在initMocks函数中Mockito会根据类中不同的注解(如@Mock, @Spy等)创建不同的mock对象,即初始化工作
MockitoAnnotations.initMocks(this);}@TestpublicvoidtestGetBlogByName(){
Blog blog=newBlog();
blog.setId(999);
blog.setTitle("文章999");
blog.setDescription("mock");
blog.setContent("mockmock");
blog.setCreated("2021-06-17 17:36:11");
blog.setStatus(0);
blog.setUser_id(89);
List<Blog> list=newArrayList<Blog>();
list.add(blog);when(userAndBlog.getBlogByName(anyString())).thenReturn(list);
System.out.println(userAndBlog.getBlogByName("zhazhahui"));}}
输出
Before Class
[Blog(id=999, user_id=89, title=文章999, description=mock, content=mockmock, created=2021-06-17 17:36:11, status=0)]
@InjectMock
在上面的例子中,我们只模拟了被测试对象的某一个方法。
但是,如果我要模拟A中引入的B,但是又不模拟A中引入的C,怎么办
package com.crud.bussiness;import com.crud.service.impl.UserServiceImpl;import org.mockito.InjectMocks;import org.mockito.Mock;import org.mockito.MockitoAnnotations;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.boot.test.context.SpringBootTest;import org.springframework.test.context.testng.AbstractTestNGSpringContextTests;import org.testng.annotations.BeforeClass;import org.testng.annotations.Test;import java.rmi.server.ExportException;importstatic org.mockito.Mockito.when;/**
* A类中依赖注入了B类,在写A的测试类时要注意:对A使用@InjectMocks注解,对于B使用@Mock注解,这样A就可以操作B了。
* @InjectMocks:创建一个实例,其余用@Mock(或@Spy)注解创建的mock将被注入到用该实例中。
* **/@SpringBootTestpublicclassUserAndBlogInjectMockBeanTestextendsAbstractTestNGSpringContextTests{@Autowired@InjectMocks
UserAndBlog userAndBlog;@Mock
UserServiceImpl userService;/**
* 前提:如果UserAndBlog上只有@InjectMocks备注
* 问题一:就是如果我不mock这个blogService的话,就无法注入blogService,就算直接Autowride blogService也是不归userAndBlog使用,就会报空指针
* 问题二:如果将@InjectMocks修改为@Autowird的话,Mock的userService就不受userAndBlog控制,如果使用mock了blogService的话,不写模拟语句,就会返回为空,
* 还是会空指针,而不是真正执行blogService的方法。
* 一个类可能会引入很多的类,总不能我要模拟其中一个,其余所有的都要mock一遍吧
* 怎么办!!!!
* 在 @InjectMocks类的上面再加一个 @Autowired就好了
* */@BeforeClasspublicvoidinitMock()throws ExportException{
System.out.println("hello mock");
MockitoAnnotations.initMocks(this);}@TestpublicvoidtestGetBlogByName(){int id=5;
String name="markerhub";when(userService.getUserIdByUserName("markerhub")).thenReturn(id);
System.out.println(userAndBlog.getBlogByName(name));}}