0

我看过例子,如何使用 mockito 调用 spring 控制器。

使用 Mock 我调用 Spring MVC 控制器。控制器调用 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;

}

问题是,我的应用程序没有调用保存方法,它没有被输入。我也没有错误。当我从 Junit 调用 save() 方法时,结果相同(我在 test() 方法中对其进行了注释)。

当我调试时,我看到 org.mockito.internal.creation.MethodInterceptorFilter 发生了中断方法

如何解决这个问题呢?发生什么了?

4

3 回答 3

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,但通常使用嵌入式数据库而不是真实的数据库。

于 2014-10-22T15:23:43.000 回答
2

只需将@InjectMocks 更改为@Autowired。这解决了问题!在这种情况下,您不是在嘲笑,而是在使用真实数据调用方法。

于 2014-11-24T12:02:50.523 回答
0

据我了解,您执行发布到“/tr/test”资源,但控制器中的请求映射是“/payment”。确保您发布到控制器中映射的资源。

于 2014-10-22T14:05:18.160 回答