I'm testing a class which injects an optional Bean and does some special handling when such bean is not available. E.g
@Service
public class FlexibleService {
@Autowired(required=false)
private UnreliableService unreliableService;
doSomething() {
if (unreliableService == null) {
// Handle it
}
}
}
The question is: how do I setup this scenario in my JUnit and Mockito test case?
So far, this is what I have.
@ExtendWith(MockitoExtension.class)
class FlexibleServiceTest {
@InjectMocks
FlexibleService target;
@Mock
UnreliableService unreliableService;
@Test
void shouldHandleItWhenUnreliableServiceIsNotAvailable() {
unreliableService = null;
target.doSomething();
// expect handling to be made
}
However, this doesn't work as expected. The bean is injected and my handling code is not reached. How can I force the UnreliableService
bean to be provided as null
in my test case?
Of course, if the unreliableService
was public or had some setter, or even if we had an all args constructor for FlexibleService
, we could easily pass unreliableService
as null. However, none of these are supposed to happen. Is there any way to work around this?
I think you're overthinking things here - @InjectMocks
will inject the respective mocks to all of the class' fields. The easiest way of keeping a field null
is just not to provide a mock for it:
@ExtendWith(MockitoExtension.class)
class FlexibleServiceTest {
@InjectMocks
FlexibleService target;
@Test
void shouldHandleItWhenUnreliableServiceIsNotAvailable() {
// Since there's no mock for unreliableService, it's implicitly null
target.doSomething();
// expect handling to be made
}
}
Note that this may mean that this test case has its own test class because you do need to mock the unreliable service for other test cases.