gpt4 book ai didi

java - 获取 org.mockito.exceptions.misusing.PotentialStubbingProblem : Strict stubbing argument mismatch

转载 作者:行者123 更新时间:2023-12-05 01:39:32 27 4
gpt4 key购买 nike

我在我的应用程序中使用公共(public) API Nutritionix 从他们的数据库中获取有关食品成分的详细信息。我想测试一种方法,该方法向公共(public) API 发送 POST 请求以接收有关产品营养值(value)的详细信息,然后在我的应用程序的下一个过程中使用它们。

我的测试类看起来像:

@ExtendWith(MockitoExtension.class)
class CaloriesServiceTest {

@InjectMocks
private CaloriesService caloriesService;

@Mock
private RestTemplate restTemplate;

@Mock
private NutritionixHeader nutritionixHeader;

@BeforeEach
void setUp() {
caloriesService = new CaloriesService(nutritionixHeader, restTemplate);
}

@Test
void receiveNutritionInformationFromAPI() {

given(nutritionixHeader.getNutritionixAppId()).willReturn("secretID");
given(nutritionixHeader.getNutritionixAppKey()).willReturn("secretKey");

var meal1 = Meal.builder()
.mealIngredients(List.of(RecipeIngredient.builder()
.foodName("grilled fish")
.build()))
.build();
var meal2 = Meal.builder()
.mealIngredients(List.of(RecipeIngredient.builder()
.foodName("eggs")
.build()))
.build();
var meal3 = Meal.builder()
.mealIngredients(List.of(RecipeIngredient.builder()
.foodName("bacon")
.build()))
.build();

var dailyMeals = DailyMeals.builder().dailyMeals(List.of(meal1, meal2, meal3)).build();

var foodNutritional1 = FoodNutritional.builder().foodName("food name1").calories(11.1).build();
var foodNutritional2 = FoodNutritional.builder().foodName("food name2").calories(22.2).build();
var foodNutritional3 = FoodNutritional.builder().foodName("food name3").calories(33.3).build();
var foodNutritional4 = FoodNutritional.builder().foodName("food name4").calories(44.4).build();

HttpEntity<NutrientsBodyForRequest> requestBody =
new HttpEntity<>(NutrientsBodyForRequest.builder()
.query("grilled fish | eggs | bacon | burger")
.build());

given(restTemplate
.exchange("https://trackapi.nutritionix.com/v2/natural/nutrients",
HttpMethod.POST,
requestBody,
new ParameterizedTypeReference<List<FoodNutritional>>() {
}))
.willReturn(
new ResponseEntity<List<FoodNutritional>>(
List.of(
foodNutritional1,
foodNutritional2,
foodNutritional3,
foodNutritional4),
HttpStatus.OK));

//when
List<FoodNutritional> foodsNutritional =
caloriesService.receiveNutritionInformationFromAPI(dailyMeals);

assertThat(foodsNutritional.get(0).getBrandName(), is("grilled fish"));
assertEquals(3, foodsNutritional.size());

}

}

不幸的是,当我运行上面的测试时,我收到了如下异常:

org.mockito.exceptions.misusing.PotentialStubbingProblem: 
Strict stubbing argument mismatch. Please check:
- this invocation of 'exchange' method:
restTemplate.exchange(
"https://trackapi.nutritionix.com/v2/natural/nutrients",
POST,
<com.application.meal.NutrientsBodyForRequest@3c486eb1,[]>,
ParameterizedTypeReference<java.util.List<com.application.meal.FoodNutritional>>
);
-> at com.application.meal.CaloriesService.receiveNutritionInformationFromAPI(CaloriesService.java:45)
- has following stubbing(s) with different arguments:
1. restTemplate.exchange(
"https://trackapi.nutritionix.com/v2/natural/nutrients",
POST,
<com.application.meal.NutrientsBodyForRequest@afd496eb,[]>,
ParameterizedTypeReference<java.util.List<com.application.meal.FoodNutritional>>
);
-> at com.application.meal.CaloriesServiceTest.receiveNutritionInformationFromAPI(CaloriesServiceTest.java:69)
Typically, stubbing argument mismatch indicates user mistake when writing tests.
Mockito fails early so that you can debug potential problem easily.

我的服务看起来像:

@Service
public class CaloriesService {

private NutritionixHeader nutritionHeaderParam;

private RestTemplate restTemplate;

public CaloriesService(NutritionixHeader nutritionHeaderParam,
RestTemplate restTemplate) {
this.nutritionHeaderParam = nutritionHeaderParam;
this.restTemplate = restTemplate;
}

private String prepareFoodNamesForRequest(DailyMeals dailyMeals) {
return dailyMeals.getDailyMeals()
.stream()
.map(Meal::getMealIngredients)
.flatMap(Collection::stream)
.map(RecipeIngredient::getFoodName)
.collect(Collectors.joining(" | "));
}


public List<FoodNutritional> receiveNutritionInformationFromAPI(DailyMeals dailyMeals) {

String foodNamesForRequest = prepareFoodNamesForRequest(dailyMeals);

HttpHeaders headers = new HttpHeaders();
headers.set("x-app-id", nutritionHeaderParam.getNutritionixAppId());
headers.set("x-app-key", nutritionHeaderParam.getNutritionixAppKey());

HttpEntity<NutrientsBodyForRequest> request =
new HttpEntity<>(NutrientsBodyForRequest.builder()
.query(foodNamesForRequest)
.build(), headers);

ResponseEntity<List<FoodNutritional>> response =
restTemplate
.exchange(
"https://trackapi.nutritionix.com/v2/natural/nutrients",
HttpMethod.POST,
request,
new ParameterizedTypeReference<List<FoodNutritional>>() {
});

return response.getBody();
}
}

我的组件类如下:

DailyMeals.class

@Getter
@AllArgsConstructor
@EqualsAndHashCode
@Builder
class DailyMeals {

@Id
private Long id;
@OneToMany(cascade = CascadeType.ALL, mappedBy = "dailyMeals")
List<Meal> dailyMeals;
}

FoodNutritional.class

@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonIgnoreProperties(ignoreUnknown = true)
@Getter
@Setter
@Builder
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode
public class FoodNutritional {

@JsonProperty("food_name")
private String foodName;

@JsonProperty("brand_name")
private String brandName;

@JsonProperty("serving_qty")
private Integer servingQuantity;

@JsonProperty("serving_unit")
private String servingUnit;

@JsonProperty("serving_weight_grams")
private String servingWeightGrams;

@JsonProperty("nf_calories")
private Double calories;

@JsonProperty("nf_total_fat")
private Double totalFat;

@JsonProperty("nf_saturated_fat")
private Double saturatedFat;

@JsonProperty("nf_cholesterol")
private Double cholesterol;

@JsonProperty("nf_sodium")
private Double sodium;

@JsonProperty("nf_total_carbohydrate")
private Double totalCarbohydrate;

@JsonProperty("nf_dietary_fiber")
private Double dietaryFiber;

@JsonProperty("nf_sugars")
private Double sugars;

@JsonProperty("nf_protein")
private Double protein;

@JsonProperty("nf_potassium")
private Double potassium;
}

膳食类

@AllArgsConstructor
@EqualsAndHashCode
@Getter
@Builder
@Entity
public class Meal {

@Id
@GeneratedValue
private Long id;

@OneToMany(cascade = CascadeType.ALL, mappedBy = "meal")
List<RecipeIngredient> mealIngredients;
}

编辑:

对于 @Abhiram 我正在附加并且 IntelliJ 提示你建议的代码段

error

Edit2:经过深思熟虑,我认为我作为主体传递的对象的不同 HashCode 存在问题:NutrientsBodyForRequest@3c486eb1,[]NutrientsBodyForRequest@ afd496eb,[],如果这可能是问题的根源,有什么建议吗?

我想要实现的是修复此错误并检查模拟服务是否会返回所需结果的测试。我将不胜感激关于如何达到目标的建议。

最佳答案

幸运的是,在与@Abhiram合作后,我找到了解决方案。

我的 mock 中缺少参数的 ArgumentMatcher

given(restTemplate
.exchange(eq("https://trackapi.nutritionix.com/v2/natural/nutrients"),
ArgumentMatchers.eq(HttpMethod.POST),
ArgumentMatchers.any(),
ArgumentMatchers.<ParameterizedTypeReference<List<FoodNutritional>>>any()))
.willReturn(
new ResponseEntity<List<FoodNutritional>>(
foodsNutritionalStabData(),
HttpStatus.OK));

下面的方法解决了一个问题。非常感谢您的 promise 。

关于java - 获取 org.mockito.exceptions.misusing.PotentialStubbingProblem : Strict stubbing argument mismatch,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58180426/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com