0

I have a Service class like below.

public class DependantServiceImpl implements DependantService { private DependantRepository dependantRepository; private EmployeeRepository employeeRepository; private final CompanyEntity companyEntity; private final String DEPENDANT_ROLE = "dependant"; @Autowired public DependantServiceImpl( CompanyEntity companyEntity, DependantRepository dependantRepository, EmployeeRepository employeeRepository) { this.companyEntity = companyEntity; this.dependantRepository = dependantRepository; this.employeeRepository = employeeRepository; } 

I use factory method like below to get Service layer.

@Service public class DependantServiceFactoryImpl implements DependantServiceFactory { private final DependantRepository dependantRepository; private final EmployeeRepository employeeRepository; private final CompanyRepository companyRepository; @Autowired public DependantServiceFactoryImpl( CompanyRepository companyRepository, DependantRepository dependantRepository, EmployeeRepository employeeRepository) { this.dependantRepository = dependantRepository; this.employeeRepository = employeeRepository; this.companyRepository = companyRepository; } @Override public DependantService dependantServiceForCompany(String companyId) { return companyRepository.findById(companyId) .map(companyEntity -> new DependantServiceImpl( companyEntity, dependantRepository, employeeRepository)) .orElseThrow(() -> new IllegalArgumentException(String.format("Invalid Compnay Id [{%s}]", companyId))); } } 

I want to write unit tests for Service class (DependantServiceImpl) but for that, I have to get the service class through DependantServiceFactoryImpl CRUD Repository (Because all repositories extended from Hibernate CRUD repository.) injecting to the constructor. But problem is that I can't inject the repositories to DependantServiceFactoryImpl. I tried many ways like below.

@ExtendWith(SpringExtension.class) @SpringBootTest(classes = DependantServiceFactoryImpl.class) public class DependantServiceImplTest { @MockBean DependantRepository dependantRepository; @MockBean EmployeeRepository employeeRepository; @MockBean CompanyRepository companyRepository; @Autowired DependantServiceFactory dependantServiceFactory; @Test @DisplayName("Get dependant succesfully test") void getDependentsTest() { String companyId = "1"; String employeeId = "9a76bb33-772c-4c41-b2eb-eb40500d7026"; List<DependantEntity> dependantEntityList = dependantServiceFactory .dependantServiceForCompany(companyId) .getDependents(employeeId); assertTrue(dependantEntityList.size() > 0); } 

But I get below error (for full error check the link https://gist.github.com/Menuka5/de6cd71b6e39e0895cf9be4e7ba34b3d)

java.lang.IllegalArgumentException: Invalid Compnay Id [{1}]

Can someone point out a way to create working Unit tests, please. Thanks in Advance. :)

1 Answer 1

1

There are 3 big mistakes here:

  1. It's supposed to be a unit test of DependantServiceImpl, so no, you don't need to call your factory to get a service instance. You also don't need SpringExtension, MockBean and Autowired. You just need to call the constructor of DependantServiceImpl passing a real entity, and mock instances (created with Mockito) of the repositories.
  2. You annotated the DependantServiceImpl constructor with Autowired, but that makes no sense, since DependantServiceImpl is not a Spring bean, is not created by Spring, and can't possibly be injected with CompanyEntity since that's not a Spring bean.
  3. If you want your test to stay as is and work, you need to mock the companyRepository.findById() method and make it return a non-empty Optional. Otherwise, of course, the value it returns is an empty Optional, so the orElseThrow() callback is called, and you get that exception.
Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.