[英]Mocked method returning NullPointerException
I want to test a method which will add headers to my GET request in order to establish a connection with public API. 我想测试一种将标头添加到我的GET请求中的方法,以便与公共API建立连接。 My service with business logic looks like:
我的带有业务逻辑的服务如下所示:
@Service
public class RestTemplateFacade {
private NutritionixHeader nutritionHeaderParam;
private RestTemplate restTemplate;
public RestTemplateFacade(
NutritionixHeader nutritionHeaderParam,
RestTemplate restTemplate) {
this.nutritionHeaderParam = nutritionHeaderParam;
this.restTemplate = restTemplate;
}
public ResponseEntity<Products> addHeaderToRequest(String queryParam) {
HttpHeaders headers = new HttpHeaders();
headers.set("x-app-id", nutritionHeaderParam.getNutritionixAppId());
headers.set("x-app-key", nutritionHeaderParam.getNutritionixAppKey());
UriComponentsBuilder uriBuilder = UriComponentsBuilder
.fromHttpUrl("https://trackapi.nutritionix.com/v2/search/instant")
.queryParam("query", queryParam);
HttpEntity httpEntity = new HttpEntity(headers);
return
restTemplate
.exchange(
uriBuilder.toUriString(),
HttpMethod.GET,
httpEntity,
Products.class);
}
}
NutritionixHeader.class looks like: NutritionixHeader.class看起来像:
@PropertySource("classpath:nutritionix.properties")
@Configuration
@Getter
@NoArgsConstructor
public class NutritionixHeader {
@Value("${nutritionix-app-id}")
private String NutritionixAppId;
@Value("${nutritionix-app-key}")
private String NutritionixAppKey;
}
My test class looks like: 我的测试类如下:
@ExtendWith(MockitoExtension.class)
@MockitoSettings(strictness = Strictness.LENIENT)
class RestTemplateFacadeTest {
@Mock
private NutritionixHeader nutritionixHeader;
@Mock
private RestTemplate restTemplate;
@InjectMocks
private RestTemplateFacade restTemplateFacade;
@Mock
private UriComponentsBuilder uriComponentsBuilder;
@BeforeEach
void setUp() {
restTemplateFacade = new RestTemplateFacade(nutritionixHeader, restTemplate);
}
@Test
void addHeaderToRequest() {
//given
var query = "query";
given(nutritionixHeader.getNutritionixAppId()).willReturn("x-app-id");
given(nutritionixHeader.getNutritionixAppKey()).willReturn("x-app-key");
//when
ResponseEntity<Products> productsResponse = restTemplateFacade.addHeaderToRequest(query);
HttpHeaders headers = productsResponse.getHeaders();
//then
assertEquals("x-app-id",
headers.entrySet()
.stream()
.filter(entry -> entry.getKey().equals("x-app-id"))
.map(Entry::getValue)
.flatMap(Collection::stream)
.findFirst()
.orElse(""));
then(nutritionixHeader).should(times(1)).getNutritionixAppId();
}
Problem occurs in the line: 该行中出现问题:
HttpHeaders headers = productsResponse.getHeaders();
with NullPointerException. NullPointerException。
All I need is the ability to test if my method has correctly added headers to my GET query. 我所需要的就是能够测试我的方法是否已将标题正确添加到GET查询中。
I am a little bit confused because it seems that I mocked everything properly but still receiving null pointer. 我有点困惑,因为似乎我对所有内容都进行了适当的嘲笑,但仍然收到空指针。 Maybe my NPE is related to the fact there is no mock for my RestTemplate object.
也许我的NPE与我的RestTemplate对象没有模拟的事实有关。 If it's true I will be grateful for suggestions on how to fix this problem.
如果是真的,我将不胜感激为您提供有关如何解决此问题的建议。
You need use ArgumentCaptor to catch HttpEntity and then get the headers. 您需要使用ArgumentCaptor捕获HttpEntity,然后获取标头。 Have a look at the code:
看一下代码:
@Test
void addHeaderToRequest() {
//given
var query = "query";
given(nutritionixHeader.getNutritionixAppId()).willReturn("x-app-id");
given(nutritionixHeader.getNutritionixAppKey()).willReturn("x-app-key");
//when
restTemplateFacade.addHeaderToRequest(query);
//then
ArgumentCaptor<HttpEntity> httpEntityCapture = ArgumentCaptor.forClass(HttpEntity.class);
String url = "https://trackapi.nutritionix.com/v2/search/instant?query=query";
verify(restTemplate).exchange(eq(url), eq(HttpMethod.GET), httpEntityCapture.capture(), eq(Products.class));
HttpHeaders headers = httpEntityCapture.getValue().getHeaders();
assertEquals("x-app-id",
headers.entrySet()
.stream()
.filter(entry -> entry.getKey().equals("x-app-id"))
.map(Map.Entry::getValue)
.flatMap(Collection::stream)
.findFirst()
.orElse(""));
then(nutritionixHeader).should(times(1)).getNutritionixAppId();
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.