无法使用 DAO mock 编写集成测试控制器?
Impossible to write integration test controller with DAO mock?
我疯了,我尝试了各种测试运行程序的所有可能组合和可能的注释进行测试,最接近我需要的解决方案如下:
@RunWith(SpringRunner.class)
@SpringBootTest(classes = {MyApplication.class})
@WebAppConfiguration
public class MyControllerTest {
MockMvc mockMvc;
// My DAO is an interface extending JpaRepository
@Mock
MyDAO myDAO;
@Autowired
WebApplicationContext webApplicationContext;
@Before
public void setUp() throws Exception {
List<MyItem> myItems = new ArrayList(){{
// Items init ...
}}
Mockito.when(myDAO.findAll()).thenReturn(myItems);
/* Other solution I tried with different annotations:
* given(myDAO.findAll()).willReturn(myItems);
* this.mockMvc = MockMvcBuilders.standaloneSetup(myController).build();
*/
this.mockMvc = webAppContextSetup(webApplicationContext).build();
}
@After
public void tearDown() throws Exception {
// Mockito.reset(myDAO);
}
@Test
public void getItems() {
String res = mockMvc.perform(get("/items"))/*.andExpect(status().isOk())*/.andReturn().getResponse().getContentAsString();
assertThat(res, is("TODO : string representation of myItems ..."));
assertNull(res); // For checking change in test functionning
}
}
我很好地在我的控制器方法和服务方法中进入了调试模式,但是当我看到 DAO 类型时,它不是 Mock 并且 findAll() 总是 return 空 ArrayList(),即使我这样做了:
Mockito.when(myDAO.findAll()).thenReturn(myItems);
我没有引发异常,我的 DAO 没有被嘲笑,尽管我找到了所有 tuto,但我不知道该怎么做。
我找到的最接近我需要的教程是 Unit Test Controllers with Spring MVC Test 但还不够,因为他想将模拟服务注入控制器以测试控制器,我想将模拟 DAO 注入到注入控制器的真实服务中(我想测试控制器+ 服务)。
在我看来,我已经通过在测试 class 上使用注释来做到这一点,它指定了 class 必须由 spring 应用程序在测试模式下实例化的内容以及什么class 不得不被嘲笑,但我不记得 '-_-.
需要你的帮助,这让我发疯!
非常感谢!!!
对于@Mock注解你需要额外的初始化:
@Before
public void initMocks() {
MockitoAnnotations.initMocks(this);
}
或者将 runner 更改为 @RunWith(MockitoJUnitRunner...
,但在这种情况下不确定 spring 上下文初始化。
我终于喜欢了(但不满意,因为它不模拟 HSQLDB 数据库,它创建了一个测试数据库),而我想模拟 DAO :
@RunWith(SpringRunner.class)
@SpringBootTest(classes = {MySpringApplication.class})
@WebAppConfiguration
public myTestClass {
MockMvc mockMvc;
@Autowired
ItemDAO itemDAO;
@Autowired
WebApplicationContext webApplicationContext;
@Before
public void setUp() throws Exception {
this.mockMvc = webAppContextSetup(webApplicationContext).build();
}
@After
public void tearDown() throws Exception {
itemDAO.deleteAll();
}
@Test
public void testMethod() {
// DB init by saving objects: create a item and save it via DAO, use real test DB
// Only mocking about rest call:
String res = mockMvc.perform(get("/items")).andExpect(status().isOk()).andReturn().getResponse().getContentAsString();
}
}
我疯了,我尝试了各种测试运行程序的所有可能组合和可能的注释进行测试,最接近我需要的解决方案如下:
@RunWith(SpringRunner.class)
@SpringBootTest(classes = {MyApplication.class})
@WebAppConfiguration
public class MyControllerTest {
MockMvc mockMvc;
// My DAO is an interface extending JpaRepository
@Mock
MyDAO myDAO;
@Autowired
WebApplicationContext webApplicationContext;
@Before
public void setUp() throws Exception {
List<MyItem> myItems = new ArrayList(){{
// Items init ...
}}
Mockito.when(myDAO.findAll()).thenReturn(myItems);
/* Other solution I tried with different annotations:
* given(myDAO.findAll()).willReturn(myItems);
* this.mockMvc = MockMvcBuilders.standaloneSetup(myController).build();
*/
this.mockMvc = webAppContextSetup(webApplicationContext).build();
}
@After
public void tearDown() throws Exception {
// Mockito.reset(myDAO);
}
@Test
public void getItems() {
String res = mockMvc.perform(get("/items"))/*.andExpect(status().isOk())*/.andReturn().getResponse().getContentAsString();
assertThat(res, is("TODO : string representation of myItems ..."));
assertNull(res); // For checking change in test functionning
}
}
我很好地在我的控制器方法和服务方法中进入了调试模式,但是当我看到 DAO 类型时,它不是 Mock 并且 findAll() 总是 return 空 ArrayList(),即使我这样做了:
Mockito.when(myDAO.findAll()).thenReturn(myItems);
我没有引发异常,我的 DAO 没有被嘲笑,尽管我找到了所有 tuto,但我不知道该怎么做。 我找到的最接近我需要的教程是 Unit Test Controllers with Spring MVC Test 但还不够,因为他想将模拟服务注入控制器以测试控制器,我想将模拟 DAO 注入到注入控制器的真实服务中(我想测试控制器+ 服务)。
在我看来,我已经通过在测试 class 上使用注释来做到这一点,它指定了 class 必须由 spring 应用程序在测试模式下实例化的内容以及什么class 不得不被嘲笑,但我不记得 '-_-.
需要你的帮助,这让我发疯!
非常感谢!!!
对于@Mock注解你需要额外的初始化:
@Before
public void initMocks() {
MockitoAnnotations.initMocks(this);
}
或者将 runner 更改为 @RunWith(MockitoJUnitRunner...
,但在这种情况下不确定 spring 上下文初始化。
我终于喜欢了(但不满意,因为它不模拟 HSQLDB 数据库,它创建了一个测试数据库),而我想模拟 DAO :
@RunWith(SpringRunner.class)
@SpringBootTest(classes = {MySpringApplication.class})
@WebAppConfiguration
public myTestClass {
MockMvc mockMvc;
@Autowired
ItemDAO itemDAO;
@Autowired
WebApplicationContext webApplicationContext;
@Before
public void setUp() throws Exception {
this.mockMvc = webAppContextSetup(webApplicationContext).build();
}
@After
public void tearDown() throws Exception {
itemDAO.deleteAll();
}
@Test
public void testMethod() {
// DB init by saving objects: create a item and save it via DAO, use real test DB
// Only mocking about rest call:
String res = mockMvc.perform(get("/items")).andExpect(status().isOk()).andReturn().getResponse().getContentAsString();
}
}