0

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

4

2 回答 2

0

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

所以我建议你的 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. 您使用@MockMockito 的实现RestTemplate在测试的上下文中创建一个 Mock 实例
  4. @InjectMocks注释放在您的 MyService 实现上对 Mockito 说“在可能的情况下将 Mocks 注入此实例”
  5. Mockito 将 MockRestTemplate注入到您的服务实例中

然后,您可以继续正常编写测试,然后使用 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 文档
于 2013-08-30T09:06:16.397 回答
0

我会写几个新的类 -RestTemplateWrapperRestTemplateWrapperFactory. 前者应该有一个内部,并且只暴露您想要与之交互的RestTemplate那些部分,包括. 要实例化,您将使用.RestTemplategetForObjectRestTemplateWrapperRestTemplateWrapperFactory

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

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

于 2013-08-29T23:21:45.700 回答