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



在我正在工作的应用程序中,我们必须使用来自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方法。因此,我想知道是否有一种方法可以拦截对该方法的调用并模拟答案。

我将编写两个新类——RestTemplateWrapperRestTemplateWrapperFactory。前者的内部应该有一个RestTemplate,并且只暴露出RestTemplate中您想要与之交互的部分,包括getForObject。要实例化RestTemplateWrapper,您将使用RestTemplateWrapperFactory

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

到了测试的时候,您将使用Mockito或EasyMock等mocking框架来创建一个mock RestTemplateWrapperFactory,并将其存根,以便它创建RestTemplateWrapper的mock,以及您想要的getForObject的任何行为。然后将您的模拟RestTemplateWrapperFactory注入到您正在测试的任何类中。

我认为您应该能够通过在您的服务实例上使用Mockito @InjectMocks注释提供RestTemplate@Mock来实现您想要的,而不必在RestTemplate周围使用任何包装器。

因此,我建议您的测试类如下所示:

@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实现在测试上下文中创建一个Mock RestTemplate实例
  4. @InjectMocks注释放在您的MyService实现上对Mockito说:"在可能的情况下,将Mocks注入到这个实例中。"
  5. Mockito将Mock RestTemplate注入您的服务实例

然后,您可以继续正常编写测试,然后使用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文档

相关内容

  • 没有找到相关文章

最新更新