如何在单元测试中模拟REST API? [英] How to Mock REST API in unit testing?

查看:100
本文介绍了如何在单元测试中模拟REST API?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用RestTemplate exchange HttpMethod.POST方法发布到端点.在我的测试文件中,我正在测试POST方法的success.但是,在当前测试中,发出POST请求时得到401 Unauthorized error.在测试文件中发出POST请求时,我需要模拟API的帮助

I am using RestTemplate exchange HttpMethod.POST method to POST to an endpoint. In my test file I am testing for success of the POST method. However with my current tests I am getting 401 Unauthorized error when POST request is made. I need help to Mock the API while making POST request in test file

这是我的主文件


@Component
public class DataTestRepo {

    private final RestTemplate restTemplate;
    private final String url;
    private final AllBuilder headersBuilder;

    public DataTestRepo(
            @Qualifier(Oauth.BEAN_NAME) AllBuilder headersBuilder,
            RestTemplate restTemplate, String url) {
        this.headersBuilder = headersBuilder;
        this.restTemplate = restTemplate;
        this.url = url;
    }
    public ResponseEntity<String> postJson(Set<String> results) {
        ResponseEntity<String> result = null;

        try {
            JSONObject jsonObject = new JSONObject(body);

            HttpEntity<String> request = new HttpEntity<String>(jsonObject.toString(), null);
            restTemplate.getMessageConverters().add(stringConvertor);
            result = restTemplate.exchange(url, HttpMethod.POST,
                    new HttpEntity<>(request, getHttpHeaders()), String.class);
         } 
        return result;
    }
}

这是我的测试文件

@RunWith(MockitoJUnitRunner.class)
@TestPropertySource
public class DataTestRepoTest {

    private static final String url = "http://localhost:8080/data/name";

    @Mock
    private DataTestRepo DataTestRepo;
    RestTemplate restTemplate = new RestTemplate();

    @Test
    public void restTemplateHttpPost_success() throws URISyntaxException {
        URI uri = new URI(url);
        Set<String> mockData = Stream.of("A","B").collect(Collectors.toSet());
        Map<String, String> body = new HashMap<>();
        body.put("Name", "Aws");
        JSONObject jsonObject = new JSONObject(body);

        HttpEntity<String> request = new HttpEntity<>(jsonObject.toString(), null);

        ResponseEntity<String> result = restTemplate.exchange(uri, HttpMethod.POST,
                new HttpEntity<>(request, DataTestRepo.getHttpHeaders()), String.class);

        Assert.assertEquals(201, result.getStatusCodeValue());
    }
}


推荐答案

您正在测试DataTestRepo类中的逻辑,因此您不应对其进行模拟. RestTemplate是DataTestRepo内部的一个依赖项,因此这正是您需要模拟的. 通常,它在测试中应如下所示:

You are testing the logic inside DataTestRepo class, so you should not mock it. RestTemplate is a dependency inside DataTestRepo, so this is exactly what you need to mock. In general it should look like this inside your test:

@InjectMocks
private DataTestRepo DataTestRepo;
@Mock
RestTemplate restTemplate;

此外,您还必须为模拟的依赖项提供一个返回值,如下所示:

Also, you will have to provide a return value for your mocked dependency, like this:

Mockito.when(restTemplate.exchange(ArgumentMatchers.any(), ArgumentMatchers.any(), ArgumentMatchers.any(), ArgumentMatchers.any())).thenReturn(new ResponseEntity<>(yourExpectedDataHere, HttpStatus.OK));
enter code here

这只是一个简单的例子.一个好的做法是检查传递给您的模拟的参数是否等于期望的参数.一种方法是将ArgumentMatchers.any()替换为实际的预期数据.另一个是单独验证它,就像这样:

This is just a simple example. A good practice would be to check that the arguments passed to your mock equal to the expected ones. One way would be to replace ArgumentMatchers.any() with the real expected data. Another is to verify it separately, like this:

Mockito.verify(restTemplate, Mockito.times(1)).exchange(ArgumentsMatchers.eq(yourExpectedDataHere), ArgumentsMatchers.eq(yourExpectedDataHere), ArgumentsMatchers.eq(yourExpectedDataHere), ArgumentsMatchers.eq(yourExpectedDataHere));

这篇关于如何在单元测试中模拟REST API?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆