Search code examples
javaspringspring-bootjunitmockito

How to mock dependency in service class from Junit


I am trying to write the test cases of one of my service method. I am packing error like cannot invoke

Cannot invoke "com.company.app.models.Product.getId()" because "product" is null

This is my service class

@Service
@Log4j2
@Transactional
@RequiredArgsConstructor(onConstructor = @__({ @Autowired, @Lazy }))
public class SomeService {

  private final AccountRepository accountRepository;
  private final AccountMapper accountMapper;
  private final ProductService productService;
 

  public Account doSomeOperation(AccountRequest accountRequest) throws ResourceNotFoundException {
    Product product = productService.findByName(accountRequest.getProductName());
    Account account = (accountRequest.getId() != null) ? accountRepository.findById(accountRequest.getId())
        .orElseThrow(() -> new ResourceNotFoundException("Account Not found with id - " + accountRequest.getId()))
        : new Account();

    accountMapper.merge(accountRequest, account);
    account.setProductId(product.getId());
    return accountRepository.save(account);
  }

This is my service class

@WebMvcTest(MigrationService.class)


class MigrationServiceTest {


    @Mock
    private AccountRepository accountRepository;

    @Mock
    private ProductService productService;

    @Mock
    private AccountMapper mapper;

    @InjectMocks
    private SomeService someService;

    
 @Test
 void testDoSomeOperation() throws ResourceNotFoundException {
    // Arrange
    AccountRequest accountRequest = new AccountRequest();
    accountRequest.setProductName(“myProduct”);
    Product product = new Product();
    product.setId(1L);
    when(accountRepository.findById(any())).thenReturn(java.util.Optional.of(new Account()));
    when(accountRepository.save(any(Account.class))).thenReturn(new Account());

    // Act
    Account migratedAccount = migrationService.migrateAccount(accountRequest);

    // Assert
    assertNotNull(migratedAccount);
    assertEquals(product.getId(), migratedAccount.getProductId());
    // Add more assertions as needed
}


}

Now I have checked the myProduct in database table which is available in database. But In this life I am not getting the value is null Product product = productService.findByName(accountRequest.getProductName());

What is I am missing ?


Solution

  • You are passing mocked instance of productService but you aren't mocking method findByName. And hence when this method is called on mocked instance you are getting null as a return value. Add below line to mock the method on product service.

    when(productService.findByName(any())).thenReturn(new Product());