Reputation: 5504
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. :)
Upvotes: 0
Views: 458
Reputation: 691635
There are 3 big mistakes here:
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.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.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.Upvotes: 1