NullPointerException Test mockito - junit

I want to test a method with Mokito but I have some errors... I received NullPointerException
This is the method that I want to test:
public String getLastModificationDate(EPTestCase testCase) {
checkArgument(testCase != null, "TestCase cannot be null.");
TestCase testCaseDMO = testCaseService.getTestCaseByID(testCase.getUID());
Date lastModificationDate = testCaseDMO.getLastModificationDate();
return DATE_FORMAT.format(lastModificationDate);
}
This is my test:
#Test
public void getLastModificationDataWihtValidTestCase() {
String testCaseUid = "testCaseUid";
String lastModificationDate = "16-05-2019 10:39:03";
EPTestCase testCase = mock(EPTestCase.class);
TestCase testCaseDMO = mock(TestCase.class);
SimpleDateFormat DATE_FORMAT = mock(SimpleDateFormat.class);
Date date = mock(Date.class);
when(testCaseService.getTestCaseByID(testCaseUid)).thenReturn(testCaseDMO);
when(testCaseDMO.getLastModificationDate()).thenReturn(date);
String result = sut.getLastModificationDate(testCase);
assertEquals(lastModificationDate, result);
}
When I debug the test I see that testCaseDMO is null, but I don't know how to fix it. .. I don't understand very well how to test something...

Related

Mocking a mongo find query and java into method

I have following query in the method:
public String getWrapperAttribute(String id, int counter) {
List<ResWrapper> wrapperList = new ArrayList<>();
String key = "Test";
String id = "Test";
objcollection.find(eq(key, id)).comment("Running the first query").into(wrapperList);
if (wrapperList.size() > 0) {
ResWrapper wrapperObj = wrapperList.get(0);
return wrapperObj .getField().getAttribute();
}
I want to unit test the method and want to mock the find query but keep getting NPE.
My unit test method:
#InjectMocks
Reader reader;
#Mock
MongoCollection<ResWrapper>objcollection;
#Mock
FindIterable<ResWrapper> findIterable;
#Test
public void getWrapperAttribute_Test() {
MongoCursor cursor = mock(MongoCursor.class);
ArrayList<ResWrapper> wrapperList = new ArrayList<>();
ResWrapper resWrapper = new ResWrapper();
Res res = new Res();
Res.setAttribute("1234545");
ResWrapper.setField(res);
WrapperList.add(ResWrapper);
Bson filter1 = eq("Test","Test");
when(objcollection.find(filter1)).thenReturn(findIterable);
when(findIterable.into(new ArrayList<>())).thenReturn(WrapperList)
reader.getWrapperAttribute("Test", 1);
}
I keep getting there is no find(Bson) for the type reader.
Is there anyway around this, this is existing code, just writing junit test case for it.

mock.method call returns null after stubbing

I am trying to test using Mockito
my class under test is
#Service
public class DynatraceAPIServiceImpl implements DynatraceAPIService {
private String apiUrl = "someurl";
private String apiToken = "sometoken";
#Override
public CreateCustomMetricResponse createCustomMetric(CreateCustomMetricRequest request) throws MonitoringException {
logger.info("Inside create custom metric");
if (request == null) {
logger.error("create metric request is null");
throw new MonitoringException("Create metric request is null");
}
String metricId = DynatraceConstants.METRIC_ID;
String displayName = request.getDisplayName();
CreateCustomMetricResponse response = httpUtils.postCustomMetric(apiUrl + "/v1/timeseries/" + metricId, apiToken, request);
if (response == null) {
logger.error("Error in creating custom metric with name : " + displayName);
throw new MonitoringException("Error in creating custom metric with name : " + displayName);
}
logger.info("Custom metric : " + displayName + " is created successfully.");
return response;
}
}
and my Test class is :
#RunWith(MockitoJUnitRunner.class)
public class DynatraceAPIServiceImplTest {
#InjectMocks
DynatraceAPIServiceImpl dynatraceAPIServiceImpl;
#Mock
DynatraceHttpUtils httpUtilsMock;
#Mock
DynatraceMonitoringUtils monitoringUtilsMock;
#Test(expected = MonitoringException.class)
public void createCustomMetricGetsNonNullResponse() throws MonitoringException {
CreateCustomMetricRequest mockRequest = CreateCustomMetricRequest.builder()
.displayName(DISPLAY_NAME)
.types(new String[] {"test-type"})
.build();
CreateCustomMetricResponse response = CreateCustomMetricResponse.builder()
.displayName(DISPLAY_NAME)
.types(new String[] {"test-type"})
.timeseriesId(TIMESERIES_ID)
.build();
boolean val = true;
when(monitoringUtilsMock.isValidMetricIdValue(anyString())).thenReturn(val);
when(httpUtilsMock.postCustomMetric(API_URL + "/v1/timeseries/" + METRIC_ID, API_TOKEN, mockRequest)).thenReturn(response);
CreateCustomMetricResponse actualRespnose = dynatraceAPIServiceImpl.createCustomMetric(mockRequest);
//verify(httpUtilsMock, times(1)).postCustomMetric(anyString(), anyString(), any(CreateCustomMetricRequest.class));
//assertEquals(actualRespnose.getDisplayName(), DISPLAY_NAME);
}
}
Here, when I execute the tests, it always end up having the response value to be null in line
CreateCustomMetricResponse response = httpUtils.postCustomMetric(apiUrl + "/v1/timeseries/" + metricId, apiToken, request);
Even if I have used when() statement to return response as I have created, it is returning null.
Really appreciate if someone can let me know what is wrong here. Thanks.
That normally happens when the params your production code uses differ from the ones that you stubbed the call with, an easy way to find out is to write the test like this
when(httpUtilsMock.postCustomMetric(any(), any(), any())).thenReturn(response);
CreateCustomMetricResponse actualRespnose = dynatraceAPIServiceImpl.createCustomMetric(mockRequest);
verify(httpUtilsMock).postCustomMetric(API_URL + "/v1/timeseries/" + METRIC_ID, API_TOKEN, mockRequest);
If you do that, you'll get a nicer error showing the difference between what your code did and what you verified it for
A better approach in general is to use 'strict stubs' so if your code does anything different to what you stubbed the mock for you'll get a nice error telling you what, where and why

Can't read Mocked Java.io.Reader

I want to test following code with Mockito:
public static String funcToTest(String query) throws Exception {
String url = Config.getURL(serviceName);
HttpClient client = new HttpClient();
HttpMethod method = new GetMethod(url);
String resultantString= "";
method.setQueryString(URIUtil.encodeQuery(query));
client.executeMethod(method);
if (method.getStatusCode() == HttpStatus.SC_OK) {
Reader reader = new InputStreamReader(method
.getResponseBodyAsStream());
int charValue = 0;
StringBuffer sb = new StringBuffer(1024);
while ((charValue = reader.read()) != -1) {
sb.append((char) charValue);
}
resultantString = sb.toString();
}
method.releaseConnection();
return resultantString;
}
I created the test like following:
#Test
public void testFunc() throws Exception{
HttpMethod method = Mockito.mock(HttpMethod.class);
InputStream inputStream = Mockito.mock(InputStream.class);
Reader reader = Mockito.mock(Reader.class);
when(method.getResponseBodyAsStream()).thenReturn(inputStream);
PowerMockito.whenNew(Reader.class).withArguments(eq(inputStream)).thenReturn(reader);
Mockito.when(reader.read()).thenReturn((int)'1', -1);
String actualResult = cls.funcToTest("");
String expected = "1";
assertEquals(expected, actualResult);
}
But the reader.read() method is not returning 1. Instead it always returns -1. How should I mock Reader so that read() method will return something else other than -1.
Thanks.
First of all , your test code is doing lots of .class mocking to mock function local variables / references. Mocking is for class dependencies and not for function local variables.
As written, you can't test your function funcToTest with mocking alone. You need to rewrite this function if not willing to use real objects for - HttpMethod & Reader.
You need to remove object creation code with new outside this function if you wish to mock calls on those objects and replace code of new with this get method. e.g.
protected HttpMethod getHttpMethod(String Url){
return new GetMethod(url);
}
Also, I don't see you mocking this line for a fake URL - it seems necessary for unit testing.
String url = Config.getURL(serviceName);
After taking object creation code outside your function, you need to create a new class than extends your SUT ( Subject Under Test ) and you override these methods ( getHttpMethod) to provide fake/mocked instances.
You need to write similar method to get Reader instance.
Then you test this new class - extended from your SUT since object creation logic need not to be tested.
Without taking object creation code outside the function, I don't see a way of mocking it by mockito.
Hope it helps !!
It must work, I'm sorry what make you slightly confused )
// annotations is very important, cls I your tested class name, i assume cls is yours
#RunWith(PowerMockRunner.class)
#PrepareForTest({cls.class})
public class PrinterTest {
#Test
public void print() throws Exception {
String url = "";
GetMethod method = Mockito.mock(GetMethod.class);
InputStream inputStream = Mockito.mock(InputStream.class);
InputStreamReader reader = Mockito.mock(InputStreamReader.class);
Mockito.when(method.getResponseBodyAsStream()).thenReturn(inputStream);
//forgot about it )
PowerMockito.whenNew(GetMethod.class).withArguments(eq(url)).thenReturn(method);
PowerMockito.whenNew(InputStreamReader.class).withArguments(eq(inputStream)).thenReturn(reader);
Mockito.when(reader.read()).thenReturn((int) '1', -1);
when(method.getStatusCode()).thenReturn(HttpStatus.SC_OK);
String actualResult = cls.funcToTest(url);
String expected = "1";
assertEquals(expected, actualResult);
}
}

How to deserialize Jackson Json NULL String to Date with JsonFormat

I have looked a lot but still couldn't get the answer so far, any help is really appreciated!
I have a simple String to Date field mapping and try to read a JSON string to Java object.
#JsonInclude(value=Include.NON_EMPTY)
#JsonFormat(shape=JsonFormat.Shape.STRING, pattern="dd-MMM-yyyy", timezone="PST")
protected Date eolAnnounceDate;
However I am getting the following exception if the JSON string value is empty.
Can you someone tell me how to get around this? I have tried a few options but they are all for serialization.
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.setSerializationInclusion(Include.NON_NULL);
objectMapper.setSerializationInclusion(Include.NON_EMPTY);
Exception :
java.lang.IllegalArgumentException: Failed to parse Date value 'NULL' (format: "dd-MMM-yyyy"): Unparseable date: "NULL"
com.fasterxml.jackson.databind.deser.std.DateDeserializers$DateBasedDeserializer._parseDate(DateDeserializers.java:180)
com.fasterxml.jackson.databind.deser.std.DateDeserializers$DateDeserializer.deserialize(DateDeserializers.java:279)
com.fasterxml.jackson.databind.deser.std.DateDeserializers$DateDeserializer.deserialize(DateDeserializers.java:260)
com.fasterxml.jackson.databind.deser.SettableBeanProperty.deserialize(SettableBeanProperty.java:464)
com.fasterxml.jackson.databind.deser.impl.MethodProperty.deserializeAndSet(MethodProperty.java:98)
com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:295)
com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:121)
com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:230)
com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:207)
com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:23)
com.fasterxml.jackson.databind.deser.SettableBeanProperty.deserialize(SettableBeanProperty.java:464)
com.fasterxml.jackson.databind.deser.impl.MethodProperty.deserializeAndSet(MethodProperty.java:98)
com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:295)
com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:121)
com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:2888)
com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:2034)
com.cisco.cre.dao.impl.ElasticsearchDAOImpl.getListByIdsFilter(ElasticsearchDAOImpl.java:94)
Thanks
- Atul
Your problem is not that a null value is passed in the JSON. The problem is that the JSON contains a string that has the value "NULL".
So, in order to fix this there are a number of available approaches. I think that the following two will work for this case.
Alternative 1: Fix the JSON
The first alternative is to fix the JSON so that it does not contain the the string value "NULL" and instead contain the value null (not quoted) or simply skip it.
Imagine the following POJO:
public class DatePojo {
#JsonInclude(value= JsonInclude.Include.NON_EMPTY)
#JsonFormat(shape=JsonFormat.Shape.STRING, pattern="dd-MMM-yyyy", timezone="PST")
#JsonProperty("date")
private Date date;
}
The following test shows that valid dates, empty values and null values work:
#Test
public void testJson() throws IOException {
String jsonWithValidDate = "{\"date\":\"12-Jun-1982\"}";
String jsonWithNoDate = "{}";
String jsonWithNullDate = "{\"date\":null}";
ObjectMapper mapper = new ObjectMapper();
final DatePojo pojoWithValidDate = mapper.readValue(jsonWithValidDate, DatePojo.class);
final DatePojo pojoWithNoDate = mapper.readValue(jsonWithNoDate, DatePojo.class);
final DatePojo pojoWithNullDate = mapper.readValue(jsonWithNullDate, DatePojo.class);
Assert.assertNotNull(pojoWithValidDate.date);
Assert.assertNull(pojoWithNoDate.date);
Assert.assertNull(pojoWithNullDate.date);
}
However, if you pass along the value "NULL" the test fails since "NULL" can not be parsed as a date:
#Test(expected = JsonMappingException.class)
public void testInvalidJson() throws IOException {
String jsonWithNullString = "{\"date\":\"NULL\"}";
ObjectMapper mapper = new ObjectMapper();
mapper.readValue(jsonWithNullString, DatePojo.class); // Throws the exception
Assert.fail();
}
Alternative 2: provide your own converter that handles "NULL"
If it is not possible to fix the JSON (as described in alternative 1) you can provide your own converter.
Setup your pojo like this instead:
public class DatePojo {
#JsonProperty("date")
#JsonDeserialize(converter = MyDateConverter.class)
private Date date;
}
And provide a converter along the lines of:
public class MyDateConverter extends StdConverter<String, Date> {
#Override
public Date convert(final String value) {
if (value == null || value.equals("NULL")) {
return null;
}
try {
return new SimpleDateFormat("dd-MMM-yyyy").parse(value);
} catch (ParseException e) {
throw new IllegalStateException("Unable to parse date", e);
}
}
}
Then, you should be all set. The following test passes:
#Test
public void testJson() throws IOException {
String jsonWithValidDate = "{\"date\":\"12-Jun-1982\"}";
String jsonWithNoDate = "{}";
String jsonWithNullDate = "{\"date\":null}";
String jsonWithNullString = "{\"date\":\"NULL\"}"; // "NULL"
ObjectMapper mapper = new ObjectMapper();
final DatePojo pojoWithValidDate = mapper.readValue(jsonWithValidDate, DatePojo.class);
final DatePojo pojoWithNoDate = mapper.readValue(jsonWithNoDate, DatePojo.class);
final DatePojo pojoWithNullDate = mapper.readValue(jsonWithNullDate, DatePojo.class);
final DatePojo pojoWithNullStr = mapper.readValue(jsonWithNullString, DatePojo.class); // Works
Assert.assertNotNull(pojoWithValidDate.date);
Assert.assertNull(pojoWithNoDate.date);
Assert.assertNull(pojoWithNullDate.date);
Assert.assertNull(pojoWithNullStr.date); // Works
}
IMO, the best approach is to use alternative 1 where you simply change the JSON.

Mocking an ArrayList using PwerMock

i am trying to mock an arraylist as follows using Powermock
MockDao Class
PowerMockito.mockStatic(DailyReceiptsAndExceptionsDetailsDao.class);
PowerMockito.mockStatic(UtilityFunctions.class);
DailyReceiptsAndExceptionsExport dailyExceptionsExport = Mockito.mock(DailyReceiptsAndExceptionsExport.class);
List<DailyReceiptsAndExceptionsDetailsGridDto> resultList = getDailyExceptions(inputDto);
try{
PowerMockito.whenNew(DailyReceiptsAndExceptionsExport.class).withArguments(Mockito.any(DailyReceiptsAndExceptionsDetailsInputDto.class)).thenReturn(dailyExceptionsExport);
Mockito.when(DailyReceiptsAndExceptionsDetailsDao.getDailyReceiptsAndExceptions(Mockito.any(DailyReceiptsAndExceptionsDetailsInputDto.class))).thenReturn(resultList);
Mockito.when(UtilityFunctions.processReportSchedule(scheduleId, jobId,dailyExceptionsExport,(List<DailyReceiptsAndExceptionResultDTO>)Mockito.any(), null, null)).thenReturn(true);
}catch(Exception e){
}
I need to write tests for the following class.
public static Response getOutboundAvgCubeAndWeightUtilization(
#QueryParam("dc") String dc,
#QueryParam("asn") String asn,
#QueryParam("sortBy") String sort,
#QueryParam("isExport") boolean isExport,
#QueryParam("fileType") String fileType,
#QueryParam("scheduleId") BigDecimal scheduleId,
#QueryParam("jobId") BigDecimal jobId) {
ResponseDTO responseDto = new ResponseDTO();
DailyReceiptsAndExceptionsDetailsInputDto inputDto = new DailyReceiptsAndExceptionsDetailsInputDto ();
inputDto.setAsn(asn);
inputDto.setDc(dc);
inputDto.setSortBy(sort);
inputDto.setFileType(fileType);
inputDto.setExport(isExport);
String filePath = "";
try {
DailyReceiptsAndExceptionResultDTO resultDto = DailyReceiptsAndExceptionsDetailsBusinessManager.getInstance().manageDailyReceiptsAndExceptionsDetails(inputDto);
List<DailyReceiptsAndExceptionResultDTO> resultsList = new ArrayList<DailyReceiptsAndExceptionResultDTO>();
resultsList.add(resultDto);
if(scheduleId != null) {
boolean responseStatus = UtilityFunctions.processReportSchedule(scheduleId, jobId, new DailyReceiptsAndExceptionsExport(inputDto), resultsList, null,null);
responseDto.setResult(Boolean.toString(responseStatus));
return CommonUtil.convertResponseToJson(responseDto);
}
}
My tests class is as follows.
#Test
public void testGetOutboundAvgCubeAndWeightUtilization_4()
throws Exception {
String dc = "5854";
String asn = "*";
String sort = "SKU";
boolean isExport = false;
String fileType = "";
BigDecimal scheduleId = new BigDecimal(100);
BigDecimal jobId = new BigDecimal(100);
DailyReceiptsAndExceptionsDetailsInputDto inputDto = new DailyReceiptsAndExceptionsDetailsInputDto ();
inputDto.setAsn(asn);
inputDto.setDc(dc);
inputDto.setSortBy(sort);
inputDto.setFileType(fileType);
inputDto.setExport(isExport);
DailyReceiptsAndExceptionsDetailsMockDAO.mockgetDailyExceptions(inputDto, scheduleId, jobId);
Response result = DailyReceiptsAndExceptionsDetailsService.getOutboundAvgCubeAndWeightUtilization(dc, asn, sort, isExport, fileType, scheduleId, jobId);
String output = result.getEntity().toString();
assertEquals(true,output.contains("\"result\": \"true\""));
}
when iam running the test case, it was throwing error because, i think the mocking of the list is not correct.
Can anybody tell how to run this test scenario ....
Your mocks appear to be fine.
JUnit is failing the test because the line
assertEquals(true,output.contains("\"result\": \"true\""));
is failing: this means that your String output does not contain the text "result": "true"
Perhaps one way for you to figure out what is wrong is to either print out the value of output prior to the assertEquals() call or use a debugger to see what the value of output is.
As a side note, assertEquals(true, <condition>) is very verbose, you can use assertTrue(<condition>) instead.
According to your comment the test is simply failing. (AssertionErrors are JUnit's way of saying that your test failed.)
You could get a better error message if you use Hamcrest. Therefore you have to change the last two lines of your code:
assertThat(result.getEntity(), hasToString(containsString("\"result\": \"true\"")));
Add some static imports for org.hamcrest.MatcherAssert.assertThat and org.hamcrest.Matchers.*.
The new error message may help you finding the error.