我有一个UserDAO,它具有诸如add,delete,update,getUser和getUsers之类的方法(用于操纵我的数据库)。我也有一个要通过Mockito测试的Requestmapping。这就是我所拥有的一切相关内容:
测试:
@RunWith(SpringJUnit4ClassRunner.class)
@WebMvcTest(value = UserController.class)
public class UserControllerTest
{
@Autowired
private MockMvc mockMvc;
@Mock
private UserDAO userDao;
@InjectMocks
private UserController userController;
@Before
public void setUp()
{
MockitoAnnotations.initMocks(this);
mockMvc = MockMvcBuilders
.standaloneSetup(userController)
.build();
}
@Test
public void testGetAllUsersSuccess() throws Exception{
User s = new User();
List<User> users = Arrays.asList(
new User(1,"somebody", "pass", "somebody@yahoo.com"),
new User(2, "sam", "mypass", "tom@hotmail.com"));
doReturn(users).when(userDao).getUsers();
mockMvc.perform(get("/userList"))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8_VALUE))
.andExpect(jsonPath("$", hasSize(2)))
.andExpect(jsonPath("$[0].userID", is(1)))
.andExpect(jsonPath("$[0].name", is("somebody")))
.andExpect(jsonPath("$[0].password", is("pass")))
.andExpect(jsonPath("$[0].email", is("somebody@yahoo.com")))
.andExpect(jsonPath("$[1].userID", is(2)))
.andExpect(jsonPath("$[1].name", is("sam")))
.andExpect(jsonPath("$[1].password", is("mypass")))
.andExpect(jsonPath("$[1].email", is("tom@hotmail.com")));
verify(userDao, times(1)).getUsers();
verifyNoMoreInteractions(userDao);
}
}
我有我的请求映射的UserController:
@RestController
public class UserController {
/**
*
*
* @return list of all users
*/
@RequestMapping(value = "/userList", method = RequestMethod.GET)
public List<User> user() throws Exception {
UserDAO gettingUsers = new UserDAO();
return gettingUsers.getUsers();
}
}
getUsers()方法:
public List<User> getUsers(){
try(Session session = HibernateUtil.getSessionFactory().openSession()){
return session.createQuery("from User", User.class).getResultList();
}
}
问题::执行测试时,将与数据库建立连接(这不是我想要的连接),而不是仅返回用户的UserDAO伪造实例我在模仿中列出的strong>列表。
问题:我的代码应该能够模拟userDAO方法getUsers(),使它不从数据库返回用户,而是在我返回伪造的用户列表时应该看起来像什么?通过请求“ / userList”的get方法调用它?
UPDATE =
解决方案:
我的新控制器:
@RestController
public class UserController {
private UserDAO userDAO;
public UserController (UserDAO userDAO)
{
this.userDAO = userDAO;
}
/**
*
*
* @return list of all users
*/
@GetMapping(value = "/Users", method = RequestMethod.GET)
public List<User> users() throws Exception {
return userDAO.getUsers();
}
}
在测试中所做的更改:
//...
@MockBean
private UserDAO userDao;
....
when(userDao.getUsers()).thenReturn(users);
...//
Spring找不到我的userDAO Bean,所以我在我的ApplicationConfiguration类中添加了存储该bean的包名称。这样做,Spring能够将bean注入构造函数中。
答案 0 :(得分:1)
userDao
模拟永远不会设置为被测控制器。
1)您不想使用new
来实例化Controller中的UserDAO
:
UserDAO gettingUsers = new UserDAO();
您想将其作为Spring Bean注入。
此外,还必须使依赖项可见,因为实际上不能从单元测试POV中设置它。
您可以将其注入构造函数中:
private UserDAO userDAO;
public UserController (UserDAO userDAO){
this.userDAO = userDAO;
}
2)您使用Spring Boot测试中的@MockBean
而不是Mockito中的@Mock
在运行的容器中模拟Spring bean。