Home > Software design >  Can't pass mock to the inject mock service
Can't pass mock to the inject mock service

Time:10-13

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

CodePudding user response:

Use @MockBean to create mock objects

import org.springframework.boot.test.mock.mockito.MockBean;

@MockBean
private User user;

CodePudding user response:

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();
}
  • Related