Java 如何为Resttemplate postForObject方法编写mockito junit

Java 如何为Resttemplate postForObject方法编写mockito junit,java,spring,junit,mockito,resttemplate,Java,Spring,Junit,Mockito,Resttemplate,我正在尝试将消息列表发布到RESTAPI。如何为方法postJSONData编写mockito junit,如下所示: public class PostDataService{ @Autowired RestTemplate restTemplate; @Autowired private Environment env; private HttpEntity<String> httpEntity; private HttpH

我正在尝试将消息列表发布到RESTAPI。如何为方法postJSONData编写mockito junit,如下所示:

public class PostDataService{

    @Autowired
    RestTemplate restTemplate;

    @Autowired
    private Environment env;

    private HttpEntity<String> httpEntity;

    private HttpHeaders httpHeaders;

    private String resourceURL = null;

    public PostDataService(){
    httpHeaders = new HttpHeaders();
    httpHeaders.set("Content-Type", "application/json");
    }

    public void postJSONData(List<String> data){
    try
    {
    resourceURL = env.getProperty("baseURL") + env.getProperty("resourcePath");
    httpEntity = new HttpEntity<String>(data.toString(), httpHeaders);
    String response = restTemplate.postForObject(resourceURL, httpEntity, String.class);
    }
    catch (RestClientException e) {
            LOGGER.info("ErrorMessage::" + e.getMessage());
            LOGGER.info("ErrorCause::" + e.getCause());
        }
    } 


}
公共类PostDataService{
@自动连线
rest模板rest模板;
@自动连线
私人环境署;
私有HttpEntity HttpEntity;
私有HttpHeaders HttpHeaders;
私有字符串resourceURL=null;
公共PostDataService(){
httpHeaders=新的httpHeaders();
httpHeaders.set(“内容类型”、“应用程序/json”);
}
public void postJSONData(列表数据){
尝试
{
resourceURL=env.getProperty(“baseURL”)+env.getProperty(“resourcePath”);
httpEntity=新的httpEntity(data.toString(),HttpHeader);
String response=restTemplate.postForObject(resourceURL、httpEntity、String.class);
}
捕获(RestClientException e){
LOGGER.info(“ErrorMessage::”+e.getMessage());
LOGGER.info(“ErrorCause::”+e.getCause());
}
} 
}
请帮助我如何编写。

您可以使用模拟服务器。这是一个专门针对这项工作的模拟框架

将以下依赖项添加到pom.xml:

<dependency>
    <groupId>com.github.tomakehurst</groupId>
    <artifactId>wiremock</artifactId>
    <version>2.12.0</version>
</dependency>
然后,您应该在
application.properties
(或其他地方)中定义
baseUrl
resourcePath
属性。记住,服务器将在本地主机上运行

之后,您应该模拟resourcePath的HTTP响应:

stubFor(get(urlEqualTo(resourcePath))
            .withHeader("Accept", equalTo("application/json"))
            .willReturn(aResponse()
                .withStatus(200)
                .withHeader("Content-Type", "application/json")
                .withBody(content)));
然后可以执行postJSONData方法:

postData.postJSONData();
最后,您可以验证对服务器的请求是否正确

verify(postRequestedFor(urlMatching(resourcePath))
        .withRequestBody(matching(expectedBody))
        .withHeader("Content-Type", matching("application/json")));

您可以使用Mockito来:

  • 使用模拟的
    restemplate
    环境创建
    postData
    的实例
  • 设置允许完成``postJSONData`调用的期望值
  • 验证是否正确调用了模拟的
    RestTemplate
postJSONData
方法不使用
restTemplate.postForObject()
响应,因此测试此方法的最佳方法是验证是否使用正确的参数调用了
restTemplate.postForObject()

下面是一个例子:

@RunWith(MockitoJUnitRunner.class)
public class PostDataTest {

    @Mock
    private RestTemplate restTemplate;
    @Mock
    private Environment env;

    @InjectMocks
    private PostData postData;

    @Test
    public void test_postJSONData() {
        String baseUrl = "theBaseUrl";
        String resourcePath = "aResourcePath";

        Mockito.when(env.getProperty("baseURL")).thenReturn(baseUrl);
        Mockito.when(env.getProperty("resourcePath")).thenReturn(resourcePath);

        List<String> payload = new ArrayList<>();

        postData.postJSONData(payload);

        // it's unclear from your posted code what goes into the HttpEntity so
        // this approach is lenient about its expectation
        Mockito.verify(restTemplate).postForObject(
                Mockito.eq(baseUrl + resourcePath),
                Mockito.any(HttpEntity.class),
                Mockito.eq(String.class)
        );

        // assuming that the HttpEntity is constructed from the payload passed 
        // into postJSONData then this approach is more specific
        HttpHeaders headers = new HttpHeaders();
        headers.set("Content-Type", "application/json");
        Mockito.verify(restTemplate).postForObject(
                Mockito.eq(baseUrl + resourcePath),
                Mockito.eq(new HttpEntity<>(payload.toString(), headers)),
                Mockito.eq(String.class)
        );
    }
}
@RunWith(MockitoJUnitRunner.class)
公共类PostDataTest{
@嘲弄
私有RestTemplate RestTemplate;
@嘲弄
私人环境署;
@注射模拟
私有PostData PostData;
@试验
公共无效性测试{
String baseUrl=“theBaseUrl”;
字符串resourcePath=“aResourcePath”;
Mockito.when(env.getProperty(“baseURL”))。然后返回(baseURL);
Mockito.when(env.getProperty(“resourcePath”))。然后返回(resourcePath);
列表有效负载=新的ArrayList();
postData.postJSONData(有效载荷);
//从您发布的代码中不清楚什么进入了HttpEntity,所以
//这种方法对其期望是宽容的
验证(restTemplate).postForObject(
Mockito.eq(baseUrl+resourcePath),
Mockito.any(HttpEntity.class),
Mockito.eq(String.class)
);
//假设HttpEntity是根据传递的负载构造的
//在postJSONData中,这种方法更为具体
HttpHeaders=新的HttpHeaders();
headers.set(“内容类型”、“应用程序/json”);
验证(restTemplate).postForObject(
Mockito.eq(baseUrl+resourcePath),
eq(新的HttpEntity(payload.toString(),headers)),
Mockito.eq(String.class)
);
}
}

在旁注上
postData
是类的一个不寻常的名称,OP中提供的
postJSONData
方法无法编译;它引用的是
meterReadings
,而不是
数据

问题是:你想测试什么?@Stefan Birkner:我想模拟服务并测试postJSONData方法。在这个场景中,resourceURL由实际的服务组成,我在其中通过发送正文中的消息列表发出post请求,并查看是否可以捕获响应状态代码。在这种情况下,我需要使用MockRestServiceServer吗?我尝试了这种方法,但遇到了以下错误:需要但未调用需要但未调用:restTemplate.postForObject(“,”class java.lang.String);事实上与此模拟没有任何交互。您能否通过调试确认在
postJSONData
中使用的
RestTemplate
实例确实是一个模拟?这是可行的,但如果我在发出post请求后要验证响应状态代码,情况会怎样?目前情况下,您不返回报告代码,因此无法对其进行验证。如果您修改了
postJSONData
,使其返回响应代码,那么您可以在测试中执行如下操作:
String response=postData.postJSONData(有效负载);资产质量(预期响应、响应)用处有限。
@RunWith(MockitoJUnitRunner.class)
public class PostDataTest {

    @Mock
    private RestTemplate restTemplate;
    @Mock
    private Environment env;

    @InjectMocks
    private PostData postData;

    @Test
    public void test_postJSONData() {
        String baseUrl = "theBaseUrl";
        String resourcePath = "aResourcePath";

        Mockito.when(env.getProperty("baseURL")).thenReturn(baseUrl);
        Mockito.when(env.getProperty("resourcePath")).thenReturn(resourcePath);

        List<String> payload = new ArrayList<>();

        postData.postJSONData(payload);

        // it's unclear from your posted code what goes into the HttpEntity so
        // this approach is lenient about its expectation
        Mockito.verify(restTemplate).postForObject(
                Mockito.eq(baseUrl + resourcePath),
                Mockito.any(HttpEntity.class),
                Mockito.eq(String.class)
        );

        // assuming that the HttpEntity is constructed from the payload passed 
        // into postJSONData then this approach is more specific
        HttpHeaders headers = new HttpHeaders();
        headers.set("Content-Type", "application/json");
        Mockito.verify(restTemplate).postForObject(
                Mockito.eq(baseUrl + resourcePath),
                Mockito.eq(new HttpEntity<>(payload.toString(), headers)),
                Mockito.eq(String.class)
        );
    }
}