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;
@Component
public class UserAndBlog {
@Autowired
private UserServiceImpl userServiceImpl;
@Autowired
private 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;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.when;
@SpringBootTest
public class UserAndBlogMockBeanTest {
@Mock
private UserAndBlog userAndBlog;
@BeforeClass
public void initMocks() throws Exception{
System.out.println("Before Class");
//MockitoAnnotations.initMocks(this),其中this就是单元测试所在的类,在initMocks函数中Mockito会根据类中不同的注解(如@Mock, @Spy等)创建不同的mock对象,即初始化工作
MockitoAnnotations.initMocks(this);
}
@Test
public void testGetBlogByName(){
Blog blog=new Blog();
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=new ArrayList<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;
import static org.mockito.Mockito.when;
/**
* A类中依赖注入了B类,在写A的测试类时要注意:对A使用@InjectMocks注解,对于B使用@Mock注解,这样A就可以操作B了。
* @InjectMocks:创建一个实例,其余用@Mock(或@Spy)注解创建的mock将被注入到用该实例中。
* **/
@SpringBootTest
public class UserAndBlogInjectMockBeanTest extends AbstractTestNGSpringContextTests {
@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就好了
* */
@BeforeClass
public void initMock() throws ExportException {
System.out.println("hello mock");
MockitoAnnotations.initMocks(this);
}
@Test
public void testGetBlogByName(){
int id=5;
String name="markerhub";
when(userService.getUserIdByUserName("markerhub")).thenReturn(id);
System.out.println(userAndBlog.getBlogByName(name));
}
}