Mockito org.mockito.exceptions.misusing.InvalidUseOfMatchersException:参数匹配器的使用无效!预期 0 个匹配器,记录 1 个:
Mockito org.mockito.exceptions.misusing.InvalidUseOfMatchersException: Invalid use of argument matchers! 0 matchers expected, 1 recorded:
首先我尝试为远程服务编写单元测试以获取天气并使用 restTemplate 然后实现 ClientHttpRequestInterceptor
以获取远程请求和远程响应以进行日志记录现在我尝试模拟 restTemplate 来编写单元-测试并得到以下错误
When using matchers, all arguments have to be provided by matchers.
For example:
//correct:
someMethod(anyObject(), eq("String by matcher"));
For more info see javadoc for Matchers class.
and here you here code i wrote for unit-test
@RunWith(MockitoJUnitRunner.class)
public class WeatherRemoteServiceTest {
@Mock CustomResttemplate restTemplate;
@Mock WeatherRemoteUtilies weatherUtilies;
@InjectMocks WeatherRemoteService weatherRemote;
@Test
public void testRetrieveWeather() {
ResponseEntity<String> MockResponse= new ResponseEntity<String>(HttpStatus.OK);
Mockito.when(weatherUtilies.buildRequestParams(Mockito.anyString()))
.thenReturn(Mockito.any(MultiValueMap.class));
ResponseEntity<String> responseEntity = new ResponseEntity<String>("sampleBodyString", HttpStatus.OK);
Mockito.when(restTemplate.buildRestTemplate().exchange(
Matchers.anyString(),
Matchers.any(HttpMethod.class),
Matchers.<HttpEntity<?>> any(),
Matchers.<Class<String>> any()
)
).thenReturn(responseEntity);
assertEquals(weatherRemote.retrieveWeather("ciaro").getStatusCode(), HttpStatus.OK);
}
}
这里是业务逻辑本身的代码
@Service
public class WeatherRemoteService {
private final Logger logger= LoggerFactory.getLogger(this.getClass());
@Value("${openweather.url}")
private String url;
@Autowired
private WeatherRemoteUtilies weatherUtilies;
@Autowired
private CustomResttemplate customRestTemplate;
public ResponseEntity<?> retrieveWeather(String city) {
logger.info(Constants.CLASS_NAME+this.getClass().getName()+Constants.METHOD_NAME+new Object() {}.getClass().getEnclosingMethod().getName());
logger.debug(Constants.METHOD_ARGUMENTS+city);
RestTemplate restRequest= customRestTemplate.buildRestTemplate();
HttpHeaders headers= new HttpHeaders();
headers.set("Accept",MediaType.APPLICATION_JSON_UTF8_VALUE);
UriComponentsBuilder uri= UriComponentsBuilder.fromUriString(url).
path("/data/2.5/weather")
.queryParams(weatherUtilies.buildRequestParams(city));
HttpEntity<String>entity= new HttpEntity<>(headers);
ResponseEntity<String>WeatherResponse=restRequest.exchange(uri.toUriString(), HttpMethod.GET, entity, String.class);
logger.info(Constants.END_METHOD);
return WeatherResponse;
}
}
代码 RestTemplateInterceptor
public class RestTemplateInterceptor implements ClientHttpRequestInterceptor {
private final Logger logger =LoggerFactory.getLogger(this.getClass());
@Override
public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution)
throws IOException {
logRequest(request, body);
ClientHttpResponse httpResponse= execution.execute(request, body);
logResponse(httpResponse);
return httpResponse;
}
private void logRequest(HttpRequest request, byte[] body) throws IOException {
logger.info(Constants.START_REMOTE_REQUEST);
logger.info("URI :{}", request.getURI().toString());
logger.info("Method :{}", request.getMethod().toString());
logger.info("Headers :{}", request.getHeaders().toString());
logger.info("Request body :{}", new String(body,"UTF-8").toString());
logger.info(Constants.END_REMOTE_REQUEST);
}
private void logResponse(ClientHttpResponse response) throws IOException {
logger.info(Constants.START_REMOTE_RESPONSE);
logger.info("Status code :{}", response.getStatusCode().toString());
logger.info("Status text :{}", response.getStatusText().toString());
logger.info("Headers :{}", response.getHeaders().toString());
logger.info("Response body :{}", StreamUtils.copyToString(response.getBody(), Charset.defaultCharset()));
logger.info(Constants.END_REMOTE_RESPONSE);
}
}
然后使用以下代码在 RestTemplate 工厂上设置拦截器
public class CustomResttemplate {
public RestTemplate buildRestTemplate() {
SimpleClientHttpRequestFactory simpleFactory= new SimpleClientHttpRequestFactory();
simpleFactory.setOutputStreaming(false);
ClientHttpRequestFactory factory = new BufferingClientHttpRequestFactory(simpleFactory);
RestTemplate restTemplate= new RestTemplate(factory);
restTemplate.setInterceptors(Collections.singletonList(new RestTemplateInterceptor()));
return restTemplate;
}
}
你的问题是你写的地方
.thenReturn(Mockito.any(MultiValueMap.class))
你实际上必须告诉 Mockito 要做什么 return。你不能在这里使用匹配器。匹配器用于验证,并用于设置存根的条件。您不能使用它们告诉 Mockito 从存根调用中 return 做什么。
创建特定的 MultiValueMap
以传递给 thenReturn
。
首先我尝试为远程服务编写单元测试以获取天气并使用 restTemplate 然后实现 ClientHttpRequestInterceptor
以获取远程请求和远程响应以进行日志记录现在我尝试模拟 restTemplate 来编写单元-测试并得到以下错误
When using matchers, all arguments have to be provided by matchers.
For example:
//correct:
someMethod(anyObject(), eq("String by matcher"));
For more info see javadoc for Matchers class.
and here you here code i wrote for unit-test
@RunWith(MockitoJUnitRunner.class)
public class WeatherRemoteServiceTest {
@Mock CustomResttemplate restTemplate;
@Mock WeatherRemoteUtilies weatherUtilies;
@InjectMocks WeatherRemoteService weatherRemote;
@Test
public void testRetrieveWeather() {
ResponseEntity<String> MockResponse= new ResponseEntity<String>(HttpStatus.OK);
Mockito.when(weatherUtilies.buildRequestParams(Mockito.anyString()))
.thenReturn(Mockito.any(MultiValueMap.class));
ResponseEntity<String> responseEntity = new ResponseEntity<String>("sampleBodyString", HttpStatus.OK);
Mockito.when(restTemplate.buildRestTemplate().exchange(
Matchers.anyString(),
Matchers.any(HttpMethod.class),
Matchers.<HttpEntity<?>> any(),
Matchers.<Class<String>> any()
)
).thenReturn(responseEntity);
assertEquals(weatherRemote.retrieveWeather("ciaro").getStatusCode(), HttpStatus.OK);
}
}
这里是业务逻辑本身的代码
@Service
public class WeatherRemoteService {
private final Logger logger= LoggerFactory.getLogger(this.getClass());
@Value("${openweather.url}")
private String url;
@Autowired
private WeatherRemoteUtilies weatherUtilies;
@Autowired
private CustomResttemplate customRestTemplate;
public ResponseEntity<?> retrieveWeather(String city) {
logger.info(Constants.CLASS_NAME+this.getClass().getName()+Constants.METHOD_NAME+new Object() {}.getClass().getEnclosingMethod().getName());
logger.debug(Constants.METHOD_ARGUMENTS+city);
RestTemplate restRequest= customRestTemplate.buildRestTemplate();
HttpHeaders headers= new HttpHeaders();
headers.set("Accept",MediaType.APPLICATION_JSON_UTF8_VALUE);
UriComponentsBuilder uri= UriComponentsBuilder.fromUriString(url).
path("/data/2.5/weather")
.queryParams(weatherUtilies.buildRequestParams(city));
HttpEntity<String>entity= new HttpEntity<>(headers);
ResponseEntity<String>WeatherResponse=restRequest.exchange(uri.toUriString(), HttpMethod.GET, entity, String.class);
logger.info(Constants.END_METHOD);
return WeatherResponse;
}
}
代码 RestTemplateInterceptor
public class RestTemplateInterceptor implements ClientHttpRequestInterceptor {
private final Logger logger =LoggerFactory.getLogger(this.getClass());
@Override
public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution)
throws IOException {
logRequest(request, body);
ClientHttpResponse httpResponse= execution.execute(request, body);
logResponse(httpResponse);
return httpResponse;
}
private void logRequest(HttpRequest request, byte[] body) throws IOException {
logger.info(Constants.START_REMOTE_REQUEST);
logger.info("URI :{}", request.getURI().toString());
logger.info("Method :{}", request.getMethod().toString());
logger.info("Headers :{}", request.getHeaders().toString());
logger.info("Request body :{}", new String(body,"UTF-8").toString());
logger.info(Constants.END_REMOTE_REQUEST);
}
private void logResponse(ClientHttpResponse response) throws IOException {
logger.info(Constants.START_REMOTE_RESPONSE);
logger.info("Status code :{}", response.getStatusCode().toString());
logger.info("Status text :{}", response.getStatusText().toString());
logger.info("Headers :{}", response.getHeaders().toString());
logger.info("Response body :{}", StreamUtils.copyToString(response.getBody(), Charset.defaultCharset()));
logger.info(Constants.END_REMOTE_RESPONSE);
}
}
然后使用以下代码在 RestTemplate 工厂上设置拦截器
public class CustomResttemplate {
public RestTemplate buildRestTemplate() {
SimpleClientHttpRequestFactory simpleFactory= new SimpleClientHttpRequestFactory();
simpleFactory.setOutputStreaming(false);
ClientHttpRequestFactory factory = new BufferingClientHttpRequestFactory(simpleFactory);
RestTemplate restTemplate= new RestTemplate(factory);
restTemplate.setInterceptors(Collections.singletonList(new RestTemplateInterceptor()));
return restTemplate;
}
}
你的问题是你写的地方
.thenReturn(Mockito.any(MultiValueMap.class))
你实际上必须告诉 Mockito 要做什么 return。你不能在这里使用匹配器。匹配器用于验证,并用于设置存根的条件。您不能使用它们告诉 Mockito 从存根调用中 return 做什么。
创建特定的 MultiValueMap
以传递给 thenReturn
。