Mockito 和 Spring RestTemplate 问题

问题描述 投票:0回答:1

我想测试这门课:

public class TokenIntrospector {

    private RestTemplate restTemplate;
    private String userInfoUri = "http://localhost";

    public TokenIntrospector(RestTemplate restTemplate) {
        this.restTemplate = restTemplate;
    }

    public String introspect(String data) {
        var userinfo = findUserInfo(data);
        return userinfo.name();
    }

    private UserInfo findUserInfo(String token) {

        MultiValueMap<String, String> headers = new LinkedMultiValueMap<>();
        headers.set("Accept", "application/json");
        headers.set("Authorization", format("Bearer %s", token));

        var userinfoRequest = new HttpEntity<UserInfo>(headers);

        var userinfo = restTemplate.exchange(userInfoUri,
                HttpMethod.GET,
                userinfoRequest,
                UserInfo.class);

        return userinfo.getBody();
    }
}

问题来自这一行:

restTemplate.exchange(userInfoUri,
                    HttpMethod.GET,
                    userinfoRequest,
                    UserInfo.class);

它正在调用这个方法(在Spring代码中):

public <T> ResponseEntity<T> exchange(String url, HttpMethod method,
            @Nullable HttpEntity<?> requestEntity, Class<T> responseType, Object... uriVariables)
            throws RestClientException {

        RequestCallback requestCallback = httpEntityCallback(requestEntity, responseType);
        ResponseExtractor<ResponseEntity<T>> responseExtractor = responseEntityExtractor(responseType);
        return nonNull(execute(url, method, requestCallback, responseExtractor, uriVariables));
    }

这是我的测试代码:

@ExtendWith(MockitoExtension.class)
public class TokenIntrospectorTest {

    @InjectMocks
    private TokenIntrospector tokenIntrospector;

    @Mock
    RestTemplate restTemplate;

    @Test
    public void test() {

        when(restTemplate.exchange(
                anyString(),
                any(HttpMethod.class),
                any(HttpEntity.class),
                any(Class.class),
                Optional.ofNullable(any()))
        ).thenReturn(ResponseEntity.ok(new UserInfo(
                "a")));

        String introspect = tokenIntrospector.introspect("data");

    }
}

这是我得到的错误:

org.mockito.exceptions.misusing.PotentialStubbingProblem: 
Strict stubbing argument mismatch. Please check:
 - this invocation of 'exchange' method:
    restTemplate.exchange(
    "http://localhost",
    GET,
    <[Accept:"application/json", Authorization:"Bearer data"]>,
    class com.example.UserInfo
);
    -> at com.example.TokenIntrospector.findUserInfo(TokenIntrospector.java:35)
 - has following stubbing(s) with different arguments:
    1. restTemplate.exchange(
    "",
    null,
    null,
    null,
    Optional.empty
);
      -> at com.example.TokenIntrospectorTest.test(TokenIntrospectorTest.java:32)
Typically, stubbing argument mismatch indicates user mistake when writing tests.
spring-boot mockito junit5 resttemplate
1个回答
0
投票

Optional.ofNullable(any())
毫无意义。如果对方法调用进行存根,则可以使用直接参数或only参数匹配器。
Optinnal.ofNullable(any())
不是匹配器,相当于
Optional.empty()
(但它会污染Mockito的参数匹配堆栈)。 所以也许您想说
any(Optional.class)
eq(Optional.empty())

但是您的代码仅将 4 个参数传递给交换方法,因此您必须使用 4 个参数而不是 5 个参数对调用进行存根。

when(
    restTemplate.exchange(
        eq("http://localhost),
        eq(HttpMethod.GET),
        any(HttpEntity.class),
        eq(UserInfo.class))
    .thenReturn(…);
© www.soinside.com 2019 - 2024. All rights reserved.