Home > Net >  How to test findById method?
How to test findById method?

Time:09-12

First - I've checked all previous topics around this question and none of them helped.

Having the following code:

    @DisplayName("GET RecipeUltraLight by id is successful")
    @Test
    public void givenRecipeId_whenGetRecipeDetailsById_thenReturnRecipeObject(){
        // given
        given(this.recipeRepository.findById(recipe.getId())).willReturn(Optional.of(recipe));
        given(this.recipeService.getRecipeById(recipe.getId())).willReturn(recipe);
        given(this.recipeConverter.toUltraLight(recipe)).willReturn(recipeUltraLightDto);

        // when
        RecipeUltraLightDto retrievedRecipe = recipeService.getRecipeUltraLightById(recipe.getId());

        // then
        verify(recipeRepository, times(1)).findById(recipe.getId());
        verify(recipeService, times(1)).getRecipeById(recipe.getId());
        verify(recipeConverter, times(1)).toUltraLight(recipe);

        assertThat(retrievedRecipe).isNotNull();
    }

gives me this error:

org.mockito.exceptions.misusing.WrongTypeOfReturnValue: 
Recipe cannot be returned by findById()
findById() should return Optional
***
If you're unsure why you're getting above error read on.
Due to the nature of the syntax above problem might occur because:
1. This exception *might* occur in wrongly written multi-threaded tests.
   Please refer to Mockito FAQ on limitations of concurrency testing.
2. A spy is stubbed using when(spy.foo()).then() syntax. It is safer to stub spies - 
   - with doReturn|Throw() family of methods. More in javadocs for Mockito.spy() method.

Service method:



    @Transactional(readOnly = true)
    public RecipeUltraLightDto getRecipeUltraLightById(Long id) {
        Recipe recipe = getRecipeById(id);
        RecipeUltraLightDto dto = new RecipeUltraLightDto();

        dto = recipeConverter.toUltraLight(recipe);

        return dto;
    }

    // internal use only
    @Transactional(readOnly = true)
    public Recipe getRecipeById(Long id) {
        if (id == null || id < 1) {
            return null;
        }

        return recipeRepository.findById(id)
                .orElseThrow(() -> new RecipeNotFoundException(
                        String.format("Recipe with id %d not found.", id)
                ));
    }

Setup:

@ContextConfiguration(classes = {RecipeService.class})
@ExtendWith({SpringExtension.class, MockitoExtension.class})
class RecipeServiceTest {
    @MockBean
    private RecipeConverter recipeConverter;

    @MockBean
    private RecipeRepository recipeRepository;

    @Autowired
    private RecipeService recipeService;

    private Recipe recipe;
    private RecipeUltraLightDto recipeUltraLightDto;
    @BeforeEach
    public void setup(){
        recipe = Recipe.builder()
                .id(1L)
                .name("Recipe")
                .description("Description")
                .createdAt(LocalDateTime.now())
                .difficulty(RecipeDifficulty.EASY)
                .minutesRequired(60)
                .portions(4)
                .authorId(1L)
                .views(0)
                .isVerified(false)
                .build();


        recipeUltraLightDto = RecipeUltraLightDto.builder()
                .id(1L)
                .name("Recipe")
                .build();
    }

I've tried:

  1. Optinal.ofNullable()
  2. Adding .isPresent()
  3. Getting rid of .orElseThrow and going through if statements and using .get()
  4. Kotlin

Will be glad if someone can help.

CodePudding user response:

You are creating a mock of the object you are testing and with that basically also render the mocking of the repository useless.

You should remove the line given(this.recipeService.getRecipeById(recipe.getId())).willReturn(recipe); that way it will just call the method and call the repository. Which now will return the mocked result. As that is the behavior that will now kick in.

CodePudding user response:

It is clearly mentioned that the method findById() returning Optional, you need to get Recipe by invoking Optional.get().

  • Related