先看我的controller
@Controller
public class UserController {
private UserDao userDao;
public UserController(UserDao userDao) {
this.userDao = userDao;
}
@RequestMapping("/login")
public String login(HttpServletRequest request) throws Exception {
String name = request.getParameter("name");
String password = request.getParameter("password");
if (userDao.exist(name, password)) {
return "index";
} else {
return "login";
}
}
很简单,就假如我想要去对login这个方法进行下单元测试.
假如此时我的dao是不可用的,调用直接抛出异常:
并且HttpServletRequest对象也是要项目运行才有的:
那么现在测试controller这个方法就要依赖于dao和httpServletRequest两个对象.而我只是想测试一下controller的login方法内部的逻辑而已有什么办法能够减少这种依赖关系,从而把重点放在login内部逻辑上的测试么?
那么mockito就是专门用来干这种事情的:
依赖
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-all</artifactId>
<version>1.10.19</version>
<scope>test</scope>
</dependency>
测试类:
package van.unittest.test.controller;
import org.junit.Before;
import org.junit.Test;
import org.junit.jupiter.api.BeforeEach;
import org.junit.runner.RunWith;
import org.mockito.Mockito;
import org.mockito.junit.MockitoJUnitRunner;
import van.unittest.test.dao.UserDao;
import javax.servlet.http.HttpServletRequest;
import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.when;
@RunWith(MockitoJUnitRunner.class)
public class UserControllerTest {
private UserDao userDao;
private UserController userController;
private HttpServletRequest request;
@Before
public void setUp() {
this.userDao= Mockito.mock(UserDao.class);
this.userController=new UserController(userDao);
this.request=Mockito.mock(HttpServletRequest.class);
}
@Test
public void testLoginSuccess() throws Exception {
when(request.getParameter("name")).thenReturn("van");
when(request.getParameter("password")).thenReturn("123");
when(userDao.exist(anyString(),anyString())).thenReturn(true);
assert(userController.login(request)).equals("login");
}
}
这就是去mock行为
这样就能够把重心放在login方法内部了.
answer用法:
package van.unittest.test.mockAction;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mockito;
import org.mockito.junit.MockitoJUnitRunner;
import java.util.List;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.when;
/**
* answer用于mock一个更为复杂的行为
*/
@RunWith(MockitoJUnitRunner.class)
public class Answer {
private List list;
@Before
public void setUp(){
this.list= Mockito.mock(List.class);
}
//mock一个更复杂的行为
@Test
public void answer(){
when(list.get(anyInt())).thenAnswer(invocationOnMock -> {
Integer param=invocationOnMock.getArgument(0,Integer.class);
return String.valueOf(param*10);
});
System.out.println(list.get(1));
}
}