【问题标题】:Mocking a REST call with MockRestServiceServer使用 MockRestServiceServer 模拟 REST 调用
【发布时间】:2016-10-13 09:55:16
【问题描述】:

我正在尝试编写一个 JUnit 测试用例来测试辅助类中的方法。该方法使用 REST 调用外部应用程序,我试图在 JUnit 测试中模拟这个调用。

辅助方法使用 Spring 的 RestTemplate 进行 REST 调用。

在我的测试中,我创建了一个模拟 REST 服务器和模拟 REST 模板并像这样实例化它们:

@Before
public void setUp() throws Exception {
    mockServer = MockRestServiceServer.createServer(helperClass.getRestTemplate());
}

然后我为模拟服务器播种,以便它在辅助方法进行 REST 调用时返回适当的响应:

// response is some XML in a String
mockServer
    .expect(MockRestRequestMatchers.requestTo(new URI(myURL)))
    .andExpect(MockRestRequestMatchers.method(HttpMethod.GET))
    .andRespond(MockRestResponseCreators.withStatus(HttpStatus.OK)
        .contentType(MediaType.APPLICATION_XML)
        .body(response));

当我运行测试时,辅助方法从它发出的 REST 调用中接收到空响应,并且测试失败。

帮助程序创建的 REST URL 具有查询参数,如下所示:“http://server:port/application/resource?queryparam1=value1&queryparam2=value2”。

我尝试将带有 的 URL ("http://server:port/application/resource") 都放在 "myURL" 变量中而不带查询参数(以引发匹配,以便它返回响应),但无法让模拟服务器返回任何内容。

我已尝试搜索此类代码的示例,但尚未找到与我的场景相似的任何内容。

春季版 4.1.7。

提前感谢您的帮助。

【问题讨论】:

  • 感谢您将类写入静态方法,这与许多其他来源不同,例如requestTo.

标签: java spring rest junit


【解决方案1】:

当您创建MockRestServiceServer 的实例时,您应该使用您的生产代码正在使用的RestTemplate 的现有实例。因此,请尝试将RestTemplate 注入您的测试并在调用MockRestServiceServer.createServer 时使用它——不要在您的测试中创建新的RestTemplate

【讨论】:

  • 问题是我的错误。我使用模拟的 RestTemplate 对象进行测试,而不是根据您的建议正确实例化的对象。替换后,测试成功运行。
  • 我在测试 RestTemplate 时也遇到了问题。但是,就我而言,我无权访问 RestTemplate 实例。我的助手类中的代码类似于new RestTemplate().exchange(uri,HttpMethod.GET,...)。我该如何测试。
  • 非常感谢你这么重要的一点,我从 1 个月开始就一直在努力解决这个问题。这是棘手的部分(如此明显)并且无法看到。谢谢 我们也可以模拟假客户吗?
【解决方案2】:

似乎您正在尝试测试休息客户端,休息服务器应该在其他地方进行测试。 您正在使用 RestTemplate -> 来调用服务。然后,尝试模拟 RestTemplate 及其调用结果。

@Mock
RestTemplate restTemplateMock;

和被测服务类

@InjectMocks
Service service;

比方说,Service 有一个方法被测试为

public void filterData() {
   MyResponseModel response = restTemplate.getForObject(serviceURL, MyResponseModel.class);
   // further processing with response
}

然后,要测试 filterData 方法,您需要模拟来自 restTemplate 调用的响应,例如

mockResponseModel = createMockResponse();
Mockito.when(restTemplateMock.getForObject(serviceURL, MyResponseModel.class)).thenReturn(mockResponseModel);

service.filterData();
//Other assert/verify,... go here

【讨论】:

    【解决方案3】:

    你可以创建一个新的 RestTemplate 实例,但是你必须像这样在你的 createServer 方法中传递它:

    private RestTemplate restTemplate = new RestTemplate();
    @BeforeEach
    public void setUp() {
    MockitoAnnotations.initMocks(this);
    mockServer = MockRestServiceServer.createServer(restTemplate);
    client.setRestTemplate(restTemplate);
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-12-11
      • 2015-04-26
      • 1970-01-01
      • 1970-01-01
      • 2022-12-13
      • 2018-05-22
      • 2020-05-22
      • 1970-01-01
      相关资源
      最近更新 更多