使用Spring 3.2和Mockito模拟Web服务的响应

时间:2013-08-29 22:18:39

标签: java web-services spring-mvc integration-testing mockito

在我正在使用的应用程序中,我们必须从Web服务中使用一些数据,处理它,然后将其发送到前端。现在我正在尝试编写一个集成测试,必须检查发送到前端的值的正确性。

我能够加载应用程序上下文:

@Inject
private WebApplicationContext wac;

@BeforeMethod
public void setup() throws Exception {
    MockitoAnnotations.initMocks(this);
    this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac)
        .addFilters(this.springSecurityFilterChain).build();
}

之后,如果我做了类似的事情:

mockMvc.perform(get("/url"))
    .andDo(print())
    .andExpect(status().isOk())

它工作得非常好,我得到了与浏览器相同的响应。

要使用其他API中的数据,我使用RestTemplate.getForObjetct方法。因此,我想知道是否有办法拦截对此方法的调用并嘲笑答案。

2 个答案:

答案 0 :(得分:0)

我会写几个新课程 - RestTemplateWrapperRestTemplateWrapperFactory。前者内部应该有RestTemplate,只展示您要与之互动的RestTemplate部分,包括getForObject。要实例化RestTemplateWrapper,您将使用RestTemplateWrapperFactory

现在,任何创建RestTemplate对象的类都应该重构,以允许注入RestTemplateWrapperFactory,并且只与它创建的RestTemplateWrapper对象进行交互。

当需要测试时,你将使用一个模拟框架,如Mockito或EasyMock来创建一个模拟RestTemplateWrapperFactory,并将其存根,以便它创建RestTemplateWrapper的模拟,具有任何行为你想要getForObject。然后将模拟RestTemplateWrapperFactory注入您正在测试的任何一个类中。

答案 1 :(得分:0)

我认为您应该能够通过在服务实例上使用Mockito @Mock注释提供RestTemplate @InjectMocks而无需使用任何包装RestTemplate来实现您的目标。{ 1}}。

所以我建议你的Test类看起来如下:

@Inject
private WebApplicationContext wac;

/* Inject your service implementation from your Spring ApplicationContext*/
@InjectMocks
@Inject
private MyService myService;

/* This Mock RestTemplate will be injected into your service instance by Mockito */
@Mock
private RestTemplate restTemplate;

@BeforeMethod
public void setup() throws Exception
{
     MockitoAnnotations.initMocks(this);
     this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac)
    .addFilters(this.springSecurityFilterChain).build();
}

这里实际发生了什么:

  1. 您正常构建ApplicationContext
  2. 您将服务实现的引用从ApplicationContext注入到测试中
  3. 您使用Mockito的@Mock实现在测试环境中创建模拟RestTemplate实例
  4. @InjectMocks注释放到MyService实现上对Mockito说“在可能的情况下将Mocks注入此实例”
  5. Mockito将模拟RestTemplate注入您的服务实例
  6. 然后您可以继续正常编写测试,然后使用Mockito模拟RestTemplate的操作并验证它们,例如。

    @Test
    public void testServiceUsesRestTemplateProperly()
    {
         Mockito.when(restTemplate.getForObject("http://example.com", String.class)).thenReturn("hello world");
    
        String s = myService.doSomething();
        Assert.assertEquals("hello world", s);
    
        Mockito.verify(restTemplate).getForObject("http://example.com", String.class);
    }
    

    (如果我在这里混合使用jUnit语法,请道歉)

    值得一读的更多信息:

    1. InjectMocks documentation