Mockando resultados (this.method)

Estou realizando os testes unitários de uma API que venho desenvolvendo e tive o seguinte problema: Não sei como mockar o resultado de um método referenciado com this.

Classe de Teste:

class CompanyServiceTest {
    @Mock
    private JwtEncoder jwtEncoder;
    @Mock
    private PasswordEncoder encoder;
    @Mock
    private CompanyRepository companyRepository;
    @InjectMocks
    private CompanyService companyService;

    @BeforeEach
    void setUp() {
        MockitoAnnotations.openMocks(this);
    }

    @Test
    @DisplayName("Update Company Successfully")
    void updateCompany_successful() {
        Company company = mock(Company.class);
        Set<Company> usedData = new HashSet<>();
        var token = mock(JwtAuthenticationToken.class);
        String encodedPassword = "Test Encoded Password";
        UpdateCompanyDTO data = mock(UpdateCompanyDTO.class);

        when(companyService.getCompany(token.getName())).thenReturn(company);

        when(companyRepository.findAllByNameOrCnpj(any(), any())).thenReturn(usedData);

        assertDoesNotThrow(() -> companyService.updateCompany(data, token));

        verify(company, times(1)).setName(data.name());
        verify(company, times(1)).setCnpj(data.cnpj());
        verify(company, times(1)).setPassword(encodedPassword);
        verify(companyService, times(1)).getCompany(token.getName());
        verify(companyRepository, times(1)).findAllByNameOrCnpj(any(), any());
    }
}

Classe Service:

@Service
public class CompanyService {
    private final JwtEncoder jwtEncoder;
    private final PasswordEncoder encoder;
    private final CompanyRepository companyRepository;

    public CompanyService(JwtEncoder jwtEncoder, PasswordEncoder encoder, CompanyRepository companyRepository) {
        this.encoder = encoder;
        this.jwtEncoder = jwtEncoder;
        this.companyRepository = companyRepository;
    }

    public void updateCompany(UpdateCompanyDTO data, JwtAuthenticationToken token) {
        Company company = this.getCompany(token.getName());
        Set<Company> usedData = companyRepository.findAllByNameOrCnpj(data.name(), data.cnpj());
        if(usedData.stream().anyMatch(companyValue -> !companyValue.getId().equals(company.getId())))
            throw new UsedDataException();

        company.setName(data.name());
        company.setCnpj(data.cnpj());
        company.setPassword(encoder.encode(data.password()));

        companyRepository.save(company);
    }

    public Company getCompany(String companyId) {
        return companyRepository.findById(UUID.fromString(companyId))
                .orElseThrow(NullCompanyException::new);
    }
}

O ponto é, quero mockar o resultado do método ´this.getCompany(token.getName())´ e devolver um ´mock(Company.class)´, mas não consigo fazer isso utilizando o ´when()´ por conta da referência ´this´, pesquisei algumas formas e maneiras de fazer isso mas ainda não consegui.

Grato se alguém puder me ajudar.

Para estimular o comportamento do método getCompany você teria que simular a partir do companyRepository que está contido dentro do método!

Exemplo:

final String id = UUID.randomUUID().toString();
final JwtAuthenticationToken token = Mockito.mock(JwtAuthenticationToken.class);
final Company company = Mockito.mock(Company.class);

when(token.getName()).thenReturn(id); // Como o token está mocado, ele precisa retornar o valor em String de um UUID válido que será convertido em UUID novamente no seu método getCompany
when(companyRepository.findById(anyString())).thenReturn(Optional.of(company)); // Aqui você manipula o comportamento que o método getCompany deve ter
1 curtida

Entendi, modifiquei aqui e deu tudo certo, muito obrigado!!

Pensei que, apesar do método ´this.getCompany(token.getName())´ ser da mesma classe que o método testado, eu deveria isola-lo a qualquer custo ao invés de fazer o mock dos resultados a partir de dentro.

Nesse caso não teria como pois a classe que você está testando é a mesma que possuí o método getCompany!

A premissa é, a classe/método que você está testando é a que você deve “estimular”, o que você deve mocar (ou usar uma implementação falsa) são somente as dependências que ela possuí.

1 curtida