简体   繁体   中英

Mockito - Mock not being injected for one of the testcases

I have a jsf spring application and using mockito for my unit test. I keep getting NullPointerException when i run my junit test in iEmployeeService mocking. There are not Exception for iSecurityLoginService .

Method to be mocked

@Autowired
IEmployeeService iEmployeeService;
@Autowired
ISecurityLoginService iSecurityLoginService;
public void addEvent() {

    entityEventsCreate.setTitle(entityEventsCreate.getTitle());
    entityEventsCreate.setModifiedBy(iSecurityLoginService
                .findLoggedInUserId());

    int eventId = iEmployeeService.addEmployeeTimeOff(entityEventsCreate);
}

My JUnit test is annotated with @RunWith(MockitoJUnitRunner.class)

@Mock
ISecurityLoginService iSecurityLoginService;

@Mock
IEmployeeService iEmployeeService;

@InjectMocks
ServiceCalendarViewBean serviceCalendarViewBean  = new ServiceCalendarViewBean();

@Before public void initMocks() {
           MockitoAnnotations.initMocks(this);
}

@Test
public void testSaveEvent() {
    Mockito.when(iSecurityLoginService.findLoggedInUserId()).thenReturn(1);
    serviceCalendarViewBean.getEntityEventsCreate().setTitle("Junit Event Testing");

    Mockito.when(iSecurityLoginService.findLoggedInUserId()).thenReturn(1);
    Mockito.when(iEmployeeService.addEmployeeTimeOff(Mockito.any(Events.class))).thenReturn(2);

    serviceCalendarViewBean.addEvent();
}

Not related to the question, but useful to know !

If the test is annotated with @RunWith(MockitoJUnitRunner.class) then MockitoAnnotations.initMocks(this); is not necessary (it may even cause issues when injecting), the mockito runner performs injection and additional stuffs to validate mocks.

Also having both mock init mechanisms may cause trouble with injection and stubbing, this is due to the way the lifecyle of JUnit test and how mockito unit-integration code is used :

  1. The runner will create mocks and inject those mocks in the test object.
  2. Then the @Before methods kicks in and recreate new mocks, and may not perform injection as the object is already initialized.

I solved the problem..In my spring bean, i had 2 objects for the same service interface. so the mock was being set for the first interface object.

Ex: in my bean i had,

@Autowired
IEmployeeService employeeService;
@Autowired
IEmployeeService iEmployeeService;

So the mock create for the IEmployeeservice interfaces was being inject for the first service object irrelevant for their names.

@Mock
IEmployeeService iEmployeeService;

ie, the mock object 'iEmployeeService' was injected to beans 'employeeService' .

Thank you for all those who helped..:)

Try to add this

@Before
public void initMocks() {
    MockitoAnnotations.initMocks(this);
}

One thing to take into account is if you have a non-empty constructor in your class you must call MockitoAnnotations.initMocks in your test class because InjectMocks annotation will not work, for example:

public class classA {

  @Autowired
  private ClassB classB;

  private Integer i;

  public ClassA(Integer i) {
    this.i = i;
  }

} 

Mockito will try to use that constructor and injection of mocks will fail using InjectMocks annotation, so you will need to call initMocks method instead, not sure if is a bug but this solved the problem for me.

I had a similar problem and after few researches, I found that it looks like the @InjectMocks were not working and failing silently without injecting the @AutoWired private objects ,

Solution : Change the design by making the dependencies visible through constructor,

IEmployeeService iEmployeeService;
ISecurityLoginService iSecurityLoginService;

@Autowired
public ServiceCalendarViewBean(final IEmployeeService iEmployeeService,
                final ISecurityLoginService iSecurityLoginService){
    this.iEmployeeService=iEmployeeService;
    this.iSecurityLoginService=iSecurityLoginService;
}

This link helped me in identifying how to work on @Autowired objects which is not visible

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM