【问题标题】:DAO method is not being mockedDAO 方法没有被嘲笑
【发布时间】:2019-07-21 15:25:07
【问题描述】:

我有一个 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);
    }
}

我有请求映射的用户控制器:

@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> 我在 mockito 中制作的列表。

问题:我的代码应该是什么样子才能模拟 userDAO 方法 getUsers() 以便它不会从数据库返回用户,而是在我返回伪造的用户列表时通过请求“/userList”的get方法调用它?

更新=

解决方案:

我的新控制器:

@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。

【问题讨论】:

  • 您不能使用new 创建UserDAO 的实例。你不能嘲笑它 - 它不应该在生产中工作。
  • @MockBean怎么样

标签: java spring hibernate get


【解决方案1】:

userDao 模拟永远不会设置为被测控制器。

1) 您不想在控制器中使用new 实例化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。

【讨论】:

  • “此外,您还必须使依赖项可见,因为实际上它不能从单元测试 POV 中设置”您的意思是什么?
  • 对不起。刚看到你的留言。我想你明白了:我提到了使用带有参数的构造函数。
  • 好的,非常感谢您的帮助 :) 我是 Spring 和 Mockito 的新手,所以我在正确配置它们时遇到了一些麻烦
猜你喜欢
  • 1970-01-01
  • 2020-07-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-04-23
  • 2018-12-24
相关资源
最近更新 更多