Mockito NullPointer Exception for the method called on Mock Object - java

I am getting a NPE when the first when(creditApplicationCache.getObject("")).thenRetun(response) is called. creditApplicationCache is null.
I am using mockito 2.17.jar.
I have added the #RunWith(MockitoJUnitRunner.class).
I have also tried with MockitoAnnotations.initMocks(this).
But nothing has helped. CreditApplicationCache is not getting initialized.
#RunWith(MockitoJUnitRunner.class)
public class WebServiceClientTest {
#InjectMocks
WebServiceClientImpl webServiceClientImpl;
#Mock
private ApplicationCacheImpl creditApplicationCache;
/*#Before
public void setUp() {
MockitoAnnotations.initMocks(this);
}*/
#Test
public void testWebServiceClient() throws BusinessException, SystemException {
WebServiceClientImpl webServiceClientImpl = new WebServiceClientImpl();
CreditCardDetailsResponse creditCardDetailsResponse = new CreditCardDetailsResponse();
creditCardDetailsResponse.setAccountNumber("1234567");
when(creditApplicationCache.getObject("XXXXXXX")).thenReturn(creditCardDetailsResponse);
when(webServiceClientImpl.getCreditCardDetails("1234")).thenReturn(creditCardDetailsResponse);
CreditCardDetailsResponse mockResponse = webServiceClientImpl.getCreditCardDetails("1234");
assertEquals(creditCardDetailsResponse.toString(),mockResponse.toString());
}
}
---------------------------------------------------------------------------------------------------------
WebServiceClientImpl.java
public class WebServiceClientImpl implements WebServiceClient {
#Autowired
private ApplicationCache creditApplicationCache;
public CreditCardDetailsResponse getCreditCardDetails(String id)
throws BusinessException, SystemException {
// Some Code
CreditCardDetailsResponse response = null;
response = (CreditCardDetailsResponse) creditApplicationCache.getObject(cacheKey);
if (response == null) {
try {
// More Code }
return response ;
}
}

Your problem is that you are creating the client again on the first line of the test: WebServiceClientImpl webServiceClientImpl = new WebServiceClientImpl();
#InjectMocks already constructs the annotated class, and injects all the relevant mocks, but what you do is re-create it without it, hence the NPE.
Simply remove that line and it should work

This issue might occur, when you import #Test from org.junit.jupiter.api.Test instead of org.junit.Test. Can you ensure, that you are using the correct #Test annotation?

Related

Mock method return type in java

Below is main code consist of one util class and service class using it
#PropertySource("classpath:atlas-application.properties")
public class ApacheAtlasUtils {
#Value("${atlas.rest.address}")
private String atlasURL;
#Value("${atlas.rest.user}")
private String atlasUsername;
#Value("${atlas.rest.password}")
private String atlasPassword;
private AtlasClientV2 client;
public AtlasClientV2 createClient() {
if (client == null) {
return new AtlasClientV2(new String[] {atlasURL}, new String[] {atlasUsername, atlasPassword});
} else {
return client;
}
}
}
Service Class is below :-
#Override
public Page<SearchResultDto> findFilesWithPages(QueryParent queryParent, Pageable pageable)
throws AtlasServiceException {
// Some code
client = new ApacheAtlasUtils().createClient();
//some code
}
I am writing unit test for service method and I am getting exception for createClient method asking for values for url, username and password which should not happen as this should be mocked but the mocking is giving me below error
java.lang.IllegalArgumentException: Base URL cannot be null or empty.
at com.google.common.base.Preconditions.checkArgument(Preconditions.java:141)
at org.apache.atlas.AtlasServerEnsemble.<init>(AtlasServerEnsemble.java:35)
at org.apache.atlas.AtlasBaseClient.determineActiveServiceURL(AtlasBaseClient.java:318)
at org.apache.atlas.AtlasBaseClient.initializeState(AtlasBaseClient.java:460)
at org.apache.atlas.AtlasBaseClient.initializeState(AtlasBaseClient.java:448)
at org.apache.atlas.AtlasBaseClient.<init>(AtlasBaseClient.java:132)
at org.apache.atlas.AtlasClientV2.<init>(AtlasClientV2.java:82)
at com.jlr.stratus.commons.utils.ApacheAtlasUtils.createClient(ApacheAtlasUtils.java:40)
at com.jlr.stratus.rest.service.impl.FileSearchService.findFilesWithPages(FileSearchService.java:49)
The Test code is as follows:-
private FileSearchService fileSearchService;
#Spy
private ApacheAtlasUtils apacheAtlasUtils;
#Mock
private AtlasClientV2 client;
#Before
public void setup() {
MockitoAnnotations.initMocks(this);
fileSearchService = new FileSearchService();
}
#Test
public void findFilesWithPages_searchAll() throws AtlasServiceException {
Mockito.doReturn(client).when(apacheAtlasUtils).createClient();
service.search(queryParent,pageable);
}
Your idea with spying is adequate (you can even go for mocking if you do not actually need any true implementation of that class).
The problem lies in the implementation:
// Some code
client = new ApacheAtlasUtils().createClient();
//some code
}
Instead of having the ApacheAtlasUtils as an instance variable (or a supplier method) you create the instance on the fly.
Mockito is not smart enough to catch that operation and replace the real object with you spy.
With the supplier method you can set up your test as follows:
#Spy
private FileSearchService fileSearchService = new FileSearchService();
#Spy
private ApacheAtlasUtils apacheAtlasUtils = new ApacheAtlasUtils();
#Mock
private AtlasClientV2 client;
#Before
public void setup() {
MockitoAnnotations.initMocks(this);
doReturn(apacheAtlasUtils).when(fileSearchService).getApacheUtils();
}
in your SUT:
#Override
public Page<SearchResultDto> findFilesWithPages(QueryParent queryParent, Pageable pageable)
throws AtlasServiceException {
// Some code
client = getApacheUtils().createClient();
//some code
}
ApacheAtlasUtils getApacheUtils(){
return new ApacheAtlasUtils();
}

Null Pointer exception passed by test method

Method that needs to be tested - located in AnalyticsServiceImpl.java class
public void trackSplashState(MeasurementViewEnum measurementViewEnum) {
HashMap<String, Object> data = createCommonData(measurementViewEnum);
MeasureServiceImpl.StartStatus status = mMeasureService.getLaunchStatus();
switch (status) {
case INSTALL:
data.put(APP_EVENT_INSTALL, INSTALL);
break;
case LAUNCH:
data.put(APP_EVENT_LAUNCH, LAUNCH);
break;
case UPDATE:
data.put(APP_EVENT_UPDATE, UPDATE);
break;
}
trackState(measurementViewEnum, data);
}
Test class
#Config(constants = BuildConfig.class, sdk = TestConfig.SDK)
#RunWith(RobolectricTestRunner.class)
public class AnalyticsServiceImplTest {
#Module(includes = TestAppModule.class, injects = AnalyticsServiceImplTest.class, overrides = true)
static class TestModule {
}
#Inject
AnalyticsServiceImpl analyticsServiceImpl;
#Inject
MeasureServiceImpl measureService;
#Inject
Context mContext;
#Inject
LoginService mLoginService;
#Captor
ArgumentCaptor<HashMap<String, Object>> data;
#Captor
ArgumentCaptor<String[]> varargs;
private ArgumentCaptor<MeasurementViewEnum> enumArgumentCaptor;
#Before
public void setUp() throws Exception {
Services.initialize(new AnalyticsServiceImplTest.TestModule()).inject(this);
enumArgumentCaptor = ArgumentCaptor.forClass(MeasurementViewEnum.class);
}
#After
public void tearDown() throws Exception {
}
#Test
public void trackSplashState_shouldReturnInstall_whenLaunchStatusEqualsINSTALL() throws Exception {
analyticsServiceImpl = mock(AnalyticsServiceImpl.class);
MeasureServiceMock measureServiceMock = new MeasureServiceMock();
measureServiceMock.setStatus(MeasureServiceImpl.StartStatus.INSTALL);
analyticsServiceImpl.mMeasureService = measureServiceMock;
analyticsServiceImpl.trackSplashState(MeasurementViewEnum.SPLASH);
verify(analyticsServiceImpl, times(1)).trackState(enumArgumentCaptor.capture(), data.capture());
}
}
when I run this test case I got null pointer exception at the last line. I'm a bit new to unit testing. Can you please explain what is the mistake that I have done in this code?
1) You are mocking the SUT which simply wont work:
analyticsServiceImpl = mock(AnalyticsServiceImpl.class);
You will be verifying its trackState method so you need to Spy on it:
analyticsServiceImpl = spy(new AnalyticsServiceImpl());
2) You are capturing the inputs but you are not asserting them in any way. I guess you missed that:
verify(analyticsServiceImpl, times(1)).trackState(enumArgumentCaptor.capture(), data.capture());
Map<String, Object> dataCaptured = data.getValue();
MeasurementViewEnum enumCapture = enumArgumentCaptor.getValue();
// assert these values
UPDATE:
#Before
public void setUp() throws Exception {
MockitoAnnotation.initMocks(this);
}

NullPointerException when mocking controller class

i wanted to write some tests for the method shown in the code below. I'm mocking dependencies with JMockit. For whatever reason i am getting a NullPointerException all the time and i really don't understand why that happens. I'm new to JMockit and in mocking dependencies in general. Stack Trace just shows NullPointerException thrown at line new NonStrictExpectations()
.
Method to test:
#Override
public boolean addSubject(User user, Schedule schedule, SchoolSubject subject) {
final boolean result = schedule.addSubject(subject.getHourTime(), subject);
scheduleDAO.update(schedule);
if (subject.getTeacher() != null && !subject.getTeacher().trim().isEmpty()) {
for (final TeacherEntry teacher : user.getTeachers()) {
if (subject.getTeacher().equals(teacher.getName())) {
teacher.getSubjects().add(subject.getName());
teacherDAO.update(teacher);
}
}
}
try {
userDAO.update(user);
} catch (final DuplicateUniqueFieldException e) {
throw new UnexpectedUniqueViolationException(e);
}
}
Test method:
//imports not copied
public class ScheduleManagerTest {
#Tested
ScheduleManager manager;
#Injectable
UserDAO userDAO;
#Injectable
ScheduleDAO scheduleDAO;
#Injectable
TeacherEntryDAO teacherDAO;
#Injectable
SchoolSubjectDAO schoolSubjectDAO;
#Mocked
Schedule schedule;
#Mocked
SchoolSubject subject;
#Mocked
User user;
#Test
public void testAddSubject() throws DuplicateUsernameException, DuplicateEmailException {
new NonStrictExpectations() {
{
schedule.addSubject(anyInt, (SchoolSubject) any);
result = true;
scheduleDAO.update((Schedule) any);
subject.getTeacher();
result = anyString;
subject.getTeacher().trim().isEmpty();
result = false;
user.getTeachers();
result = (ArrayList<TeacherEntry>) any;
teacherDAO.update(((TeacherEntry) any));
userDAO.update((User) any);
};
};
assertTrue(manager.addSubject(user, schedule, subject));
}
}
I think i'm doing something pretty wrong :(
It's hard to know what is going wrong based on the description, but here's a guess:
Mocked objects will return null in their methods by default. You'll get a null pointer here:
subject.getTeacher().trim()
because getTeacher() will return null. To return a teacher, you'll have to either use a real subject or do further mocking with
Mockito.when(subject.getTeacher()).thenReturn(new Teacher());
You need to add #RunWith(JMockit.class) to your class
#RunWith(JMockit.class)
public class ScheduleManagerTest {
...

java.lang.AssertionError: Expectation failure on Verify: jUnit4 TestCase

The following code returns Expectation failure of verification:
What's up with the code?
can someone help me what am I missing there?
public class DAOImplTest {
private DAOImpl dao;
private JdbcTemplate mockJdbcTemplate;
#Before
public void before() {
dao = new DAOImpl();
mockJdbcTemplate = createMock(JdbcTemplate.class);
dao.setJdbcTempate(mockJdbcTemplate);
}
#After
public void after() {
dao = null;
}
#SuppressWarnings("unchecked")
#Test
public void methReturnsWhenOrgIdsAndGuidFound(){
final String expectedOrgIds = "d514d112566e";
final String expectedGUID = "one";
expect(mockJdbcTemplate.queryForObject(eq(SSOSASguidDAOImpl.GET_GUID_FOR_ORG_IDS),
(RowMapper<String>) anyObject(), eq(expectedGUID), eq(expectedOrgIds))).andReturn(expectedOrgIds);
replay(mockJdbcTemplate);
// verify(mockJdbcTemplate, expectedOrgIds);
verify(mockJdbcTemplate);
assertNotNull(expectedOrgIds);
assertEquals("d514d112566e", expectedOrgIds);
}
}
Wondering why it is throwing an error on verify?
The call to replay should be followed by a call the the expected methods, in your case, you should call the mockJdbcTemplate.queryForObject(); method with appropriate parameters; before calling the verfiy method.

Mockito & Junit null pointer exception: name must not be null

I have been trying to run the following test using mockito and junit and I keep on getting "java.lang.NullPointerException: name must not be null"
Can anyone tell me why this is happening?
On debugging, I found out that this exception is thrown when the test executes the following statement in isStopValid(String) method:
FacilityValidationUtil facUtil = new FacilityValidationUtil();
#RunWith(MockitoJUnitRunner.class)
public class MyFormTest{
#InjectMocks MyForm form = new MyForm();
#Mock FacilityValidationUtil facUtil;
#Test
public void testIsStopValid() throws FinderException{
when(facUtil.isFacilityValid("")).thenReturn(false);
form.setOrigin("");
assertEquals(false, form.isStopValid(form.getOrigin()));
}
}
Class with method to be tested:
public class MyForm{
FacilityValidationUtil facUtil = new FacilityValidationUtil();
public boolean isStopValid(String stop){
try {
return facUtil.isFacilityValid(stop);
} catch (FinderException e) {
log.error("Error finding the stop. "+e.getCause());
return false;
}
}
}
public class FacilityValidationUtil{
private FacilityDAO facilityDao = new HibernateFacilityDAO();
public boolean isFacilityValid(String facility) throws FinderException{
boolean test;
FacilityImpl facilityImpl = facilityDao.findFacilityByNassCode(facility);
test = (facilityImpl==null)?false : true;
return test;
}
}
public class HibernateFacilityDAO extends HibernateAbstractDeltaDAO implements FacilityDAO {
public HibernateFacilityDAO() {
super(false);
}
}
Short Answer: You are trying to mock a variable (facUtil) that is local to your isStopValid method, so the mock version of this object in your test is never going to be called because you are 'newing it up" each time.
Long Answer: It looks like you are trying to mock the call to your FacilityValidationUtil class, and if this is the case, then you need to either make the class a field so that Mockito can inject the object by reflection (if this object is thread safe, which it looks like it is) or explore a mocking framework like PowerMockito that will allow you to mock a constructor (google for PowerMockito when new).
PowerMockito.whenNew(FacilityValidationUtil.class).withNoArguments().thenReturn(facUtil);
Mockito doesn't support any mocking of constructor args by default.
EDIT
If you are still having trouble, then I would suggest starting with a smaller example. I've put together one for you that works and uses the code you are trying to test (It's using inner classes though, which Mockito has some quirky rules about, but I'm just doing it to compress the example).
#RunWith(MockitoJUnitRunner.class)
public class MyFormTest {
#InjectMocks
private MyForm form = new MyForm();
#Mock
private FacilityValidationUtil facUtil;
#Test
public void testIsStopValid_false() {
when(facUtil.isFacilityValid("")).thenReturn(false);
assertEquals(false, form.isStopValid(""));
}
#Test
public void testIsStopValid_true() {
when(facUtil.isFacilityValid("")).thenReturn(true);
assertEquals(true, form.isStopValid(""));
}
public class MyForm {
private FacilityValidationUtil facUtil = new FacilityValidationUtil();
public boolean isStopValid(String stop) {
try {
return facUtil.isFacilityValid(stop);
} catch (FinderException e) {
return false;
}
}
}
public class FacilityValidationUtil {
public boolean isFacilityValid(String facility) throws FinderException {
throw new RuntimeException(facility);
}
}
public class FinderException extends RuntimeException {
public FinderException(String message) {
super(message);
}
}
}
What's really important is that your mock is not getting injected correctly. Until you get that resolved, you are going to keep getting the same error. Set a break point in your MyForm at the point you call facUtil.isFaciltyValid and look at the object. It should be a mockito object, not your class.
Good luck.

Categories