为什么 MockRestServiceServer 中需要 mockServer.verify

Why mockServer.verify is needed in MockRestServiceServer

使用MockRestServiceServerandExpect进行测试时

mockServer.expect(requestTo("/hotels/42")).andExpect(method(HttpMethod.GET))
    .andRespond(withSuccess("{ \"id\" : \"42\", \"name\" : \"Holiday Inn\"}", MediaType.APPLICATION_JSON));

如果发现意外行为,则测试失败,

例如 no further requests expected: HTTP 如果发送到意外 URL

我的配置:

@SpringBootApplication(scanBasePackages = { "..." })
public class MyConfig extends SpringBootServletInitializer {

我的测试class

@ContextConfiguration( classes = {MyConfig.class})
@ActiveProfiles("local")
@WebAppConfiguration
public class My Test extends AbstractTestNGSpringContextTests {
@Autowired
@InjectMocks
private ServiceUnderMock serviceUnderMock;
private AutoCloseable closeable;

@BeforeClass
public void initMocks() {       
    closeable = MockitoAnnotations.openMocks(this);
    mockServer = MockRestServiceServer.bindTo(restTemplate).ignoreExpectOrder(true).build();
}

@AfterClass
public void releaseMocks() throws Exception {
    closeable.close();
}

@Autowired
private RestTemplate restTemplate;

private MockRestServiceServer mockServer;
@Test
public void test() {
    try {
        mockServer.expect(ExpectedCount.min(1), 
          requestTo(new URI("https://www.google.com")))
          .andExpect(method(HttpMethod.GET));
    } catch (URISyntaxException e) {
        Assert.fail("failed to create mock");
    }    
    serviceUnderMock.doSomething();   
}

那么为什么我们需要添加 mockServer.verify()

At the end of the test use verify() to ensure all expected requests were actually performed.

MockRestServiceServer 的想法是它允许您模拟外部服务器,这样 RestTemplate 在测试期间实际上不需要将请求发送到实际服务器。相反,它只是将请求发送到此 MockRestServiceServer(认为它是一种内存服务器)并且它将 return 为相应请求配置的模拟响应。

您必须在测试前配置 MockRestServiceServer 将收到的所有预期请求及其相应的响应。

所以基本上有两件事需要验证,它们是:

  1. 对于 RestTemplate 发送的每个请求,应该在 MockRestServiceServer

    中为该请求配置一个模拟响应
  2. 对于预期在 MockRestServiceServer 上接收的所有请求,RestTemplate 应该真正发送所有这些预期的请求。

(1) 将在 RestTemplate 发出请求时自动验证。您提到的异常 no further requests expected: HTTP 是因为它失败 (1)(即忘记在 MockRestServiceServer 中存根此请求)

(2) 不会自动验证。您必须手动调用 MockRestServiceServer.verify() 才能验证它。

一个例子:

mockServer.expect(requestTo(new URI("https://www.yahoo.com")))
                .andExpect(method(HttpMethod.GET)).andRespond(withSuccess());
        
mockServer.expect(requestTo(new URI("https://www.google.com")))
                .andExpect(method(HttpMethod.GET)).andRespond(withSuccess());
        
        
mockServer.expect(requestTo(new URI("https://www.whosebug.com")))
                .andExpect(method(HttpMethod.GET)).andRespond(withSuccess());

restTemplate.getForEntity("https://www.yahoo.com", String.class);
restTemplate.getForEntity("https://www.google.com", String.class);

没有 mockServer.verify() ,尽管 RestTemplate 没有将请求发送到 MockServer 预计会收到的 https://www.whosebug.com,但测试仍然通过。

但是对于 mockServer.verify() ,它可以检查并因此无法通过测试。