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.
Related
I'm writing a Junit for a service class using Mockito. Application has been built up using Java 8, Spring 5. While my rest of test methods are running fine except this one where I'm stuck and unable to proceed further.
#RunWith(SpringRunner.class)
#SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = CommerceConnectorApplication.class)
#ActiveProfiles("test")
#AutoConfigureWebTestClient
public class CommerceRepositoryDetailsTest {
#Autowired
private RepositoryDetails repositoryDetails;
#MockBean
private AsyncRunner asyncRunner;
#MockBean
private CommerceTenantUserRepository tenantUserRepository;
#Test
public void whenUpdateCartId_ThenReturnUpdatedTenantUserDetails(){
String tenantId = "2737363";
String userId = "763sssj";
String cartId = "827";
TenantUserKey tenantUserKey = new TenantUserKey();
tenantUserKey.setTenantId(tenantId);
tenantUserKey.setUserId(userId);
CommerceTenantUser commerceTenantUser = new CommerceTenantUser(tenantUserKey, "xyz#abc.com", cartId, LocalDate.now());
Optional <CommerceTenantUser> commerceTenantUser1 = Optional.of(commerceTenantUser);
Mockito.when(tenantUserRepository.findById(tenantUserKey)).thenReturn(commerceTenantUser1);
Mono<CommerceTenantUser> actualMono = repositoryDetails.updateCartId(tenantId, userId, cartId);
CommerceTenantUser commerceTenantUser2 = actualMono.block();
assertThat(commerceTenantUser2, is(commerceTenantUser));
}
}
Error :-
2018-08-14 16:19:38.843 INFO 106888 --- [ main] c.s.c.c.c.s.CommerceRepositoryDetails : Entering updateCartId#CommerceSystemDetailService
com.sap.chatbot.commerceconnector.exception.BadRequestException: error in updating cart
at com.sap.chatbot.commerceconnector.common.security.CommerceRepositoryDetails.updateCartId(CommerceRepositoryDetails.java:139)
at com.sap.chatbot.commerceconnector.common.security.CommerceRepositoryDetails$$FastClassBySpringCGLIB$$fd3bfefe.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:746)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
at org.springframework.cache.interceptor.CacheInterceptor.lambda$invoke$0(CacheInterceptor.java:53)
at org.springframework.cache.interceptor.CacheAspectSupport.invokeOperation(CacheAspectSupport.java:337)
at org.springframework.cache.interceptor.CacheAspectSupport.execute(CacheAspectSupport.java:392)
at org.springframework.cache.interceptor.CacheAspectSupport.execute(CacheAspectSupport.java:317)
at org.springframework.cache.interceptor.CacheInterceptor.invoke(CacheInterceptor.java:61)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:688)
at com.sap.chatbot.commerceconnector.common.security.CommerceRepositoryDetails$$EnhancerBySpringCGLIB$$3b388d4d.updateCartId(<generated>)
at com.sap.chatbot.commerceconnector.CommerceRepositoryDetailsTest.whenUpdateCartId_ThenReturnUpdatedTenantUserDetails(CommerceRepositoryDetailsTest.java:124)
The main method to test :-
#Override
#CachePut(value = CommerceConnectorConstants.CommerceCache.COMMERCE_CACHE_TENANT_USER_DATA_MAP)
public Mono<CommerceTenantUser> updateCartId(String tenantId, String userId, String cartId) {
logger.info("Entering updateCartId#CommerceSystemDetailService");
final TenantUserKey commerce = getTenantUserObj(tenantId, userId);
Optional<CommerceTenantUser> tenantUser = commerceTenantUserRepository.findById(commerce);
return tenantUser.map(tenantUserObj -> updateCartIdAndRefreshMap(tenantUserObj, cartId))
.orElse(Mono.error(new BadRequestException("error in updating cart")));
}
private Mono<CommerceTenantUser> updateCartIdAndRefreshMap(CommerceTenantUser tenantUserObj, String cartId) {
tenantUserObj.setCartId(cartId);
final Mono<CommerceTenantUser> commerceTenantUser = asyncRunner
.one(() -> commerceTenantUserRepository.saveAndFlush(tenantUserObj))
.doOnNext(value -> commerceCacheService.refreshMap())
.doOnError(error -> Mono.error(new BadRequestException("Error ocurred in updating cart id ")))
.map(commerceTenantUserObj -> commerceTenantUserObj);
return commerceTenantUser;
}
The method updateCartId() calls another private method updateCartIdAndRefreshMap(). My JUnit fails in return statment in updateCartId().
Please advise on how to fix my JUnit to test this specific updateCartId() method.
I am trying to put String "0" in the parameter but in the table i`m getting 1 in the specified column.
in php script i have this code: (i removed the irrelevant code)
$isRegistered= $_POST['isRegistered'];
$sql = "INSERT INTO Users (isRegistered) VALUES ('$isRegistered')";
in my java code i have: (i removed the irrelevant code)
private static final String USER_IS_REGISTERED = "isRegistered";
private static final String FALSE = "0";
StringRequest stringRequest = new StringRequest(Request.Method.POST, URL_LINK,
#Override
protected Map<String, String> getParams() {
Map<String, String> params = new HashMap<>();
params.put(USER_IS_REGISTERED,FALSE);
return params;
}
};
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);
}
}
suppose I have a model like this:
public class Foo {
private String name;
#JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss")
private Date date;
}
and the controller is like this:
#RequestMapping("/getFoo")
public #ResponseBoddy Foo getFoo(Foo ff) {
return new ff();
}
in the client side I have done something like this:
Foo request = new Foo();
RestTeplate rest = new RestTemplate();
rest.postForObject("http://hostAddress:8080/Fooo/getFoo", request, String.class);
and my client Foo is the same as the service Foo
but something is going wrong, the content type is invalid..
my question is: is it possible to post for object using a java bean ? and how to it, and if there is guidelines where to start building and consuming web services I'll be thankfull
Since you return the Foo object in the controller, you should wirte the RestTemplate in this way:
RestTeplate rest = new RestTemplate();
rest.postForObject("http://hostAddress:8080/Fooo/getFoo", request, Foo.class);
Otherwise you can write:
#RequestMapping("/getFoo")
public #ResponseBoddy Foo getFoo(Foo ff) {
Foo ff = new Foo();
String result = null;
//Convert ff in String and valorize result
return result;
}
Hope this helps
Angelo
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.