我见过example,如何使用mockito调用spring controller。
使用Mock我调用Spring MVC控制器。 Controller调用Spring服务类。
@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
@ContextConfiguration(locations = { "file:src/main/webapp/WEB-INF/spring/root-context.xml" })
public class TestController {
@Mock
private TestService testService;
@InjectMocks
private PaymentTransactionController paymentController;
private MockMvc mockMvc;
@Before
public void setup() {
MockitoAnnotations.initMocks(this);
this.setMockMvc(MockMvcBuilders.standaloneSetup(paymentController).build());
}
@Test
public void test() throws Exception {
this.mockMvc.perform(post("/tr/test").content(...)).andExpect(status().isOk());
// testService.save(); <-- another way
}
好的,效果很好。我很好地称我的Spring控制器。但在Spring控制器中我有注入服务层。
@Autowired
private TestService serviceTest;
@RequestMapping(value = "/test", method = RequestMethod.POST)
@ResponseBody()
public String test(HttpServletRequest request) {
...
serviceTest.save();
// in save method I call dao and dao perist data;
// I have injected dao intrface in serviceTest layer
...
return result;
}
问题是,我的应用程序没有调用save方法,它没有输入。我也没有错误。同样的结果是当我从Junit调用save()方法时(我在test()方法中对它进行了评论)。
当我调试时,我看到中断方法发生在org.mockito.internal.creation.MethodInterceptorFilter
如何解决这个问题?会发生什么?
答案 0 :(得分:2)
如果您正在对控制器进行单元测试,则应该模拟服务层(您正在做什么)。在这种测试中,你只需控制:
您只需配置模拟方法的返回值(如果相关),或控制所谓的
@Before
public void setup() {
MockitoAnnotations.initMocks(this);
this.setMockMvc(MockMvcBuilders.standaloneSetup(paymentController).build());
// set return values from the mocked service
when(testService.find(1)).thenReturn(...);
}
稍后验证所谓的
@Test
public void test() throws Exception {
this.mockMvc.perform(post("/tr/test").content(...)).andExpect(status().isOk());
// testService.save(); <-- another way
verify(testService, times(1)).save();
}
如果你想进行集成测试,你不要模拟服务,而是设置一个应用程序上下文来注入真正的bean,但通常使用嵌入式数据库而不是真正的数据库。
答案 1 :(得分:2)
只需将@InjectMocks更改为@Autowired即可。这解决了这个问题!在这种情况下,您不是在嘲笑,而是使用实际数据调用方法。
答案 2 :(得分:0)
据我所知,你执行post到“/ tr / test”资源,但是你的控制器中的请求映射是'/ payment'。确保发布到控制器中映射的资源。