我想测试这门课:
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.
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(…);