Java 使用 MockRestServiceServer 模拟 REST 调用

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/37781982/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 19:40:26  来源:igfitidea点击:

Mocking a REST call with MockRestServiceServer

javaspringrestjunit

提问by GarlicBread

I'm trying to write a JUnit test case which tests a method in a helper class. The method calls an external application using REST and it's this call that I am trying to mock in the JUnit test.

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

The helper method makes the REST call using Spring's RestTemplate.

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

In my test, I create a mock REST server and mock REST template and instanitiate them like this:

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

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

I then seed the mock server so that it should return an appropriate response when the helper method makes the REST call:

然后我为模拟服务器设置种子,以便在辅助方法进行 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));

When I run my test, the helper method receives a null response from the REST call it makes and the test fails.

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

The REST URL that the helper makes has query params and looks like this: "http://server:port/application/resource?queryparam1=value1&queryparam2=value2".

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

I've tried putting the URL ("http://server:port/application/resource") both with andwithout the query parameters in the "myURL" variable (to elicit a match so that it returns a response), but can not get the mock server to return anything.

我已经尝试将带有不带有查询参数的 URL(“ http://server:port/application/resource”)放在“myURL”变量中(以引起匹配以返回响应),但可以没有让模拟服务器返回任何东西。

I've tried searching for examples of this kind of code but have yet to find anything which seems to resemble my scenario.

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

Spring version 4.1.7.

Spring 版本 4.1.7。

Thanks in advance for any assistance.

在此先感谢您的帮助。

采纳答案by Rafal G.

When you create an instance of MockRestServiceServeryou should use existing instance of RestTemplatethat is being used by your production code. So try to inject RestTemplateinto your test and use it when invoking MockRestServiceServer.createServer- don't create new RestTemplatein your tests.

当您创建一个实例时,MockRestServiceServer您应该使用RestTemplate您的生产代码正在使用的现有实例。所以尝试注入RestTemplate你的测试并在调用时使用它MockRestServiceServer.createServer- 不要RestTemplate在你的测试中创建新的。

回答by VinhNT

Seems that you are trying to test the rest-client, the rest-server should be tested in other place. You are using RestTemplate -> To call the service. Then, tried to mock RestTemplate and its call's results.

似乎您正在尝试测试rest-client,应该在其他地方测试rest-server。您正在使用 RestTemplate -> 调用服务。然后,尝试模拟 RestTemplate 及其调用的结果。

@Mock
RestTemplate restTemplateMock;

and Service Under Test Class

和服务测试类

@InjectMocks
Service service;

Let say, Service has a method to be test as

比方说,Service 有一种方法可以测试为

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

Then, to test filterData method, you need to mock the response from restTemplate call such as

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

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

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

回答by Jared Zena

You can create a new instance of RestTemplate however you have to pass it in your createServer method like this:

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

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