当前位置: 首页 > 面试题库 >

如何在单元测试中模拟REST API?

田信然
2023-03-14
问题内容

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

这是我的主文件

@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内部的一个依赖项,因此这正是您需要模拟的。通常,它在测试中应如下所示:

@InjectMocks
private DataTestRepo DataTestRepo;
@Mock
RestTemplate restTemplate;

同样,您将必须为模拟的依赖项提供一个返回值,如下所示:

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

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

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


 类似资料:
  • 我在尝试包装我的代码以用于单元测试时遇到了一些问题。问题是。我有接口IHttpHandler: 现在很明显,我将在Connection类中有一些方法,这些方法将从my后端检索数据(JSON)。但是,我想为这个类编写单元测试,显然我不想编写针对真实后端的测试,而是一个被嘲弄的测试。我曾尝试谷歌一个很好的答案,但没有很大的成功。我以前可以并且曾经使用过Moq来模拟,但是从来没有在像HttpClient

  • 我还尝试将模拟转换为文档,如下所示 但这会在代码实现内部访问MongoCollection时产生NullpointerException异常。 这两个我都试过了 null 我厌倦了用java编写相同的测试,并在其中进行泛型的转换。 有人在Kotlin有嘲弄泛型类的经验吗?

  • 问题内容: 我刚开始使用Node,现在正在编写一些单元测试。对于前几个函数,我可以正常运行,但是现在我碰到了一个包含其中的函数。我的函数的简化版本如下所示: 我尝试使用基本节点断言测试库进行测试: 由于执行此操作的时间(以及结果)总是不同的,因此它将始终失败。 在Python中,我可以设置模拟类和对象。有没有一种方法可以在Node中解决此问题而无需将moment.utc()作为函数的参数? 问题答

  • 问题内容: 我正在为启动a 并使用返回的诺言执行一些逻辑的控制器编写单元测试。我可以测试触发$ modal的父控制器,但是我一生无法弄清楚如何模拟成功的诺言。 我尝试了多种方法,包括使用和强制履行承诺。但是,我得到的最接近的结果是与本 SO帖子中的最后一个答案相似的东西。 我已经在“旧的” 模式中看到了几次这样的问题。在“新” 模式下,我找不到太多的方法。 一些指针将不胜感激。 为了说明问题,我使

  • 我想测试一些错误处理逻辑,所以我想在我的单元测试中模拟特定的异常类型。我正在嘲笑对boto3的调用,但是我想让这个mock引发一个异常。我正在测试的代码遵循以下模式: 我已经创建了一个unittest模拟,但我不知道如何使它引发异常,因为这个参数NotFound exception。我尝试了以下方法,但不起作用,因为在计算except子句时,它得到了“exceptions必须派生自基类”: 如何在

  • 为了获得可重用和可测试的rxjava代码,我使用ObservableTransformers分离了代码的各个部分。它在生产中工作得很好,但是测试它并不像预期的那么容易,因为我似乎无法模拟那些观察到的ransformers。 when(observableTransformer.apply(any())).thenreturn(observable.just(“mockedtext”)); 一旦调用