This is my PersonSeviceImpl class. Here before saving any person I want to run some validators which implements PersonValidator. And also I autowired PersonStatusChangeValidator to use in a different method.
public class PersonServiceImpl implements PersonService {
@Autowired
PersonDao personDao;
@Autowired
List<PersonStatusChangeValidator> statusChangeValidators;
@Autowired
List<PersonValidator> personValidators;
@Override
public Person save(Person person) {
for(PersonValidator validator: personValidators){
validator.validate(person);
}
personDao.save(person);
return person;
}
}
Here I am writing test to verify whether validators are called or not.
@RunWith(PowerMockRunner.class)
public class PersonServiceImplTest {
@Mock
private PersonDao personDao;
@Mock
private PersonValidator personValidator;
@Mock
private PersonStatusChangeValidator statusChangeValidator;
@Spy
private List<PersonStatusChangeValidator> statusChangeValidators = new ArrayList<>();
@Spy
private List<PersonValidator> personValidators = new ArrayList<>();
@InjectMocks
private PersonServiceImpl personService;
@Before
public void init() {
MockitoAnnotations.initMocks(this);
personValidators.add(personValidator);
statusChangeValidators.add(statusChangeValidator);
}
@Test
public void testCreatePerson() throws Exception {
personService.save(new Person());
verify(personValidator, times(1)).validate(any(Person.class));
}
}
The problem is personValidators
, statusChangeValidators
are null by the time I'm running test. And when there is a single @Spy
annotation in the test, it is working fine. Need some help to know where I'm doing wrong.
Your test doesn't show any mocking of statics or finals so I'm wondering why you are using @RunWith(PowerMockRunner.class)
?
I have taken your code and successfully run it with just one change: replacing @RunWith(PowerMockRunner.class)
with @RunWith(MockitoJUnitRunner.class)
.
So, unless there is some other aspect of your tests which require PowerMock then I'd suggest running your test case with MockitoJUnitRunner
. If there is some aspect of your tests which require PowerMock then I'd suggest injecting the statusChangeValidators
and personValidators
instances with explicit constructor injection (i.e. what @JB Nizet suggested in his comment above) so that you do not have to rely on @InjectMocks
.
FWIW, there's an open issue against PowerMock for this inability to apply @InjectMocks
for fields with the @Spy
annotation.