Issue
I have service:
@Service
class UserService {
private final Map<AbstractSomeService, CustomEnum> someMap;
public UserService(List<AbstractSomeService> someService) {
someService.forEach(service -> someMap.put(service.getCustomEnum(), service));
}
public void logicExecution() {
//code
}
}
When i am mocking as below: i am getting NullPointer:
@Mock
private SomeService someService; // Service which is extended of AbstractSomeService
@InjectMocks
private UserService userService = new UserService(Collection.singletonList(someService))
@BeforeEach
void setUp() {
MockitoAnnotations.openMocks(this);
}
@Test
public void testBrokenJunit() {
userService.logicExecution(); // NULL POINTER HERE (
}
SomeService:
@Service
public class SomeService extends AbstactSomeService() {
public CustomEnum getCustomEnum() {
return CustomEnum.BROKEN_JUNIT_TEST;
}
//logic here
}
Stack trace is quite simple:
java.lang.NullPointerException: Cannot invoke "getCustomEnum()" because "service" is null
StackTrace without constructor initialization:
org.mockito.exceptions.misusing.InjectMocksException:
Cannot instantiate @InjectMocks field named 'UserService' of type '...'.
You haven't provided the instance at field declaration so I tried to construct the instance.
However the constructor or the initialization block threw an exception : Cannot invoke "java.util.List.forEach(java.util.function.Consumer)" because "someService" is null
at
Caused by: java.lang.NullPointerException: Cannot invoke "java.util.List.forEach(java.util.function.Consumer)" because "someService" is null
at UserService.<init>
P.S.
When i am using real object of UserService, not a mock everything is ok.
But it doesn't work with @InjectMocks
Solution
Try the following in your test class (you don't need to initialize UserService
with a new instance via the constructor, @InjectMocks
will do that for you):
@Mock
private SomeService someService;
@InjectMocks
private UserService userService;
@BeforeEach
void setUp() {
MockitoAnnotations.openMocks(this);
}
@Test
public void testBrokenJunit() {
userService.logicExecution();
}
If this does not work because you have a List
and not a simple SomeService
you can do the following:
@Mock
private SomeService someService;
private UserService userService;
@BeforeEach
void setUp() {
MockitoAnnotations.openMocks(this);
userService = new UserService(Collection.singletonList(someService));
}
@Test
public void testBrokenJunit() {
userService.logicExecution();
}
Answered By - João Dias
Answer Checked By - Timothy Miller (JavaFixing Admin)