Search code examples
servicemockitojunit5

org.mockito.exceptions.misusing.PotentialStubbingProblem: Strict stubbing argument mismatch when testing service class, only one when in method


Test Class:

@ExtendWith(MockitoExtension.class) class MealItemServiceImplTest {

@Mock
private MealItemRepository mealItemRepository;

@InjectMocks
private MealItemServiceImpl mealItemService;

private User user;

private MealItem mealItem;

@BeforeEach
public void setup(){
    user = new User();
    user.setId(9999);
    user.setUsername("test_user");
    user.setPassword("password");
    user.setRole(Role.USER);

    mealItem = new MealItem();
    mealItem.setId(9999L);
    mealItem.setUserId(9999);
    mealItem.setMeal("standard meal");
    mealItem.setDate(LocalDate.parse("2023-06-09"));
    mealItem.setTime(LocalTime.parse("14:35:00"));
    mealItem.setMealSize(MealItem.MealSize.heavy);
    mealItem.setNote("test note");
}

@Test
void normal_createMealItem(){
    MealItemCreationDTO micDTO = new MealItemCreationDTO(
            "standard meal",
            LocalDate.parse("2023-06-09"),
            LocalTime.parse("14:35:00"),
            MealItem.MealSize.heavy,
            "test note"
    );

    when(mealItemRepository.save(mealItem)).thenReturn(mealItem);

    Long returnId = mealItemService.createMealItem(user, micDTO); <- ln69

    verify(mealItemRepository, times(1)).save(mealItem);
    assertEquals(mealItem.getId(), returnId);
}

Service Method: @Override public Long createMealItem(User user, @Valid MealItemCreationDTO mealItemCreationDTO) { // todo convert dto to entity // todo should user parameter be used or method level security

    MealItem mi = new MealItem();
    mi.setUserId(user.getId());
    mi.setMeal(mealItemCreationDTO.meal());
    mi.setDate(mealItemCreationDTO.date());
    mi.setTime(mealItemCreationDTO.time());
    mi.setMealSize(mealItemCreationDTO.mealSize());
    mi.setNote(mealItemCreationDTO.note());

    return mealItemRepository.save(mi).getId(); <- ln76
}

Error: org.mockito.exceptions.misusing.PotentialStubbingProblem: Strict stubbing argument mismatch. Please check:

  • this invocation of 'save' method: mealItemRepository.save( MealItem{id=null, userId=9999, meal='standard meal', date=2023-06-09, time=14:35, mealSize=heavy, note='test note', afterMealNotes=null} ); -> at com.example.meal2.mealitem.MealItemServiceImpl.createMealItem(MealItemServiceImpl.java:76)

  • has following stubbing(s) with different arguments:

    1. mealItemRepository.save( MealItem{id=9999, userId=9999, meal='standard meal', date=2023-06-09, time=14:35, mealSize=heavy, note='test note', afterMealNotes=null} ); -> at com.example.meal2.mealitem.MealItemServiceImplTest.normal_createMealItem(MealItemServiceImplTest.java:67) Typically, stubbing argument mismatch indicates user mistake when writing tests. Mockito fails early so that you can debug potential problem easily. However, there are legit scenarios when this exception generates false negative signal:
  • stubbing the same method multiple times using 'given().will()' or 'when().then()' API Please use 'will().given()' or 'doReturn().when()' API for stubbing.

  • stubbed method is intentionally invoked with different arguments by code under test Please use default or 'silent' JUnit Rule (equivalent of Strictness.LENIENT). For more information see javadoc for PotentialStubbingProblem class.

    at com.example.meal2.mealitem.MealItemServiceImpl.createMealItem(MealItemServiceImpl.java:76) at com.example.meal2.mealitem.MealItemServiceImplTest.normal_createMealItem(MealItemServiceImplTest.java:69)

What is wrong with the code? When was only called once in the test!

Similar worded search said something about using when twice, but here I have only used it once. I have tried using lenient() next to when... but i have gotten this error:

java.lang.NullPointerException: Cannot invoke "com.example.meal2.mealitem.MealItem.getId()" because the return value of "com.example.meal2.mealitem.MealItemRepository.save(Object)" is null

but why is it null since i have set the when().return() to a MealItem obj...

I am using JUnit 5, Mockito...

many thanks


Solution

  • I have solved this by using any(MealItem.class)