Getting NullPointerException while mocking in SpringBoot - java

Am trying to write a Junit Test case for one of the class. But getting error while trying to do it,
Test class looks like below -
public class IntegratorClassTest{
#InjectMocks
IntegratorClass integratorClass;
#Mock
RequestClass requestClass;
#Mock
ContentList contentResponse;
#Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
}
#Test
public void getCmsOffersTest()throws Exception{
ContentService contentService = Mockito.mock(ContentService.class);
RequestClass requestClass = Mockito.mock(RequestClass.class);
ContentList contentResponse = getContentList();
when(contentService.getContentCollection()).thenReturn(contentResponse);
Validator validator = Mockito.mock(Validator.class);
List<OfferDetails> offerList = new ArrayList<OfferDetails>();
Mockito.doNothing().when(validator).validateData(offerList);
List<OfferDetails> offerListResult = integratorClass.getCmsOffers(contentService, requestClass);
assertTrue(offerListResult.size()>0);
}
}
And the implementation class looks something like below -
public class IntegratorClass {
private static final Logger LOGGER = LoggerFactory.getLogger(IntegratorClass.class);
#Autowired
Validator validator;
public List<OfferDetails> getCmsOffers(ContentService contentService,RequestClass requestClass)throws Exception{
LOGGER.info("Entered method getCmsOffers to get the list of offers from CMS");
List<OfferDetails> offerList = new ArrayList<OfferDetails>();
ContentList contentResponse = null;
try
{
contentResponse = contentService.getContentCollection();
offerList = getOfferListFromCmsResponse(contentResponse, requestClass);
LOGGER.info("Total number of active offers we got from CMS are -" + offerList.size());
}catch (Exception e)
{
ErrorResponse errorResponse = PromotionalOffersUtilities.createErrorResponse("500", e.getMessage(),"Getting error while fetching content from CMS - getCmsOffers", ErrorResponse.Type.ERROR);
LOGGER.error("Getting error while fetching content from CMS with Error Message: " + e.getMessage());
throw new ServiceException(errorResponse, HttpStatus.INTERNAL_SERVER_ERROR);
}
//failing here
validator.validateData(offerList);
LOGGER.info("Exiting method getCmsOffers");
return offerList;
}
}
When I ran it in debug mode am error for the line validator.validateData(offerList);.
It is returning "NullPointerException".

You need to include the Validator when mocking dependencies so that it will be injected into the subject under test
#Mock
Validator validator;
Also when arranging the behavior of the validator use an argument matcher for the invoked member as the current setup wont match because they will be comparing different instances when exercising the test.
Mockito.doNothing().when(validator).validateData(any(List<OfferDetails>.class));
You are manually mocking the other dependencies within the test method so they are not needed out side of that
The test now becomes
public class IntegratorClassTest{
#InjectMocks
IntegratorClass integratorClass;
#Mock
Validator validator;
#Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
}
#Test
public void getCmsOffersTest()throws Exception{
//Arrange
ContentService contentService = Mockito.mock(ContentService.class);
RequestClass requestClass = Mockito.mock(RequestClass.class);
ContentList contentResponse = getContentList();
Mockito.when(contentService.getContentCollection()).thenReturn(contentResponse);
Mockito.doNothing().when(validator).validateData(any(List<OfferDetails>.class));
//Act
List<OfferDetails> offerListResult = integratorClass.getCmsOffers(contentService, requestClass);
//Assert
assertTrue(offerListResult.size() > 0);
}
}

Related

Problems with null pointer using mockito

I'm trying to test a method. And in this method, a new Object is instancied, but I don't want it, otherwise other class will be tested.
How I tell to mockito dont intanciate it?
#Component
#EnableScheduling
public class VerificadorDeNovasAssinaturas {
private DocuSign docuSign;
private ApiClient apiClient;
#Autowired
private DocuSignProperties docuSignProperties;
public EnvelopesInformation verificaNovasAssinaturas() throws Exception {
this.docuSign = new DocuSign(docuSignProperties); // I don't want mockito instanciate DocuSign
this.apiClient = docuSign.getApiClient();
this.apiClient.addDefaultHeader("Authorization", "Bearer " + docuSign.getoAuthToken().getAccessToken());
And my test class:
#SpringBootTest
#RunWith(SpringRunner.class)
#ActiveProfiles("test")
public class VerificadorDeNovasAssinaturasTest {
#InjectMocks
private VerificadorDeNovasAssinaturas verificador;
private DocuSignProperties docuSignProperties;
private ApiClient apiClient;
private UserInfo userInfo;
private OAuthToken oAuthToken;
#Mock
private DocuSign docuSign;
#Before
public void initialize() throws Exception {
docuSignProperties = new DocuSignProperties();
docuSignProperties.setBaseUrl("https://demo.docusign.net/restapi");
docuSignProperties.setBasePath("/restapi");
setApiClientConfigurations();
when(docuSign.getApiClient()).thenReturn(this.apiClient);
when(docuSign.getoAuthToken()).thenReturn(this.oAuthToken);
...}
private void setApiClientConfigurations() throws Exception {
this.apiClient = new ApiClient(this.docuSignProperties.getBaseUrl());
this.oAuthToken = getOAuth();
... }
#Test
public void testaVerificacaoDeNovasAssinaturas() throws Exception {
EnvelopesInformation results = verificador.verificaNovasAssinaturas();
assertNotNull(results);
}
I don't want mockito instanciate a new DocuSign, because this is not the reason of the test. There is some way do ignore this step?
Well, Mockito can not change something if your code( Code to be tested, Which you intend to) does something, However you can mock it so that it does not create a new object (rather have your "Mocked Object"), so that you can verify something against the expected behavior.
In your code if you change few lines , you can achieve what you want, like -
Create a DocuSignService class and there you create this new object in say some - getDocuSign method. Then your code looks something like below -
#Autowired
private DocuSignService docuSignService ;
this.docuSign = new DocuSign(docuSignProperties); // This is what you have
this.docuSign = this.docuSignService.getDocuSign() ; // This is new code
Now in your test case -
#Mock
DocuSignService docuSignService ;
#Mock
private DocuSign docuSign;
//.
//.
Mockito.when(this.docuSignService.getDocuSign()).thenReturn(docuSign);
Now you have control on this object.
I resolved it using powerMockito.
DocuSign docuSign = PowerMockito.mock(DocuSign.class);
PowerMockito.whenNew(DocuSign.class).withAnyArguments().thenReturn(docuSign);

Test the service in springboot

This is the service I have :
#Service
public class UserInfoService {
#Autowired
private UserInfoServiceClient UserInfoServiceClient; // Call another Rest API
public ResponseEntity<ResponseUserInfoData> sendUserInfo(String UserId) throws RuntimeException {
ResponseUserInfoData responseUserInfoData = new ResponseUserInfoData();
//Get the body from the User service client
UserServiceDTO UserServiceDTO = UserInfoServiceClient.sendResponse(UserId).getBody();
//Set the values of responseUserInfoData
Optional<UserServiceDTO> UserServiceDTOOptional = Optional.ofNullable(UserServiceDTO);
if (UserServiceDTOOptional.isPresent()) {
UserServiceDTOOptional.map(UserServiceDTO::getId).ifPresent(responseUserInfoData::setid);
}
else return ResponseEntity.noContent().build();
}
}
I have to test it. I'm new to JUnit testing. I want to test the following points:
To check if the service return the response entity
To check if the get and set method works
This is what I started?
#RunWith(MockitoJUnitRunner.class)
public class ServiceTests {
#InjectMocks
private UserInfoService UserInfoService;
#Mock
private UserInfoServiceClient UserInfoServiceClient;
#Mock
private UserServiceDTO UserServiceDTO;
#Test
public void shouldReturnUserInfoData() throws IOException{
UserInfoService.sendUserInfo("ABC");
}
}
Any help is appreciated?
Mockito is useful to mock the dependencies of the service so that you can test all the code path in you service. In your case you will want to stub the call to serInfoServiceClient.sendResponse(UserId) and have it return a specific UserServiceDTO for each test case.
The test file looks like it is set up correctly, you only need to mock the method to give you the result you need for the particular test, for example
#RunWith(MockitoJUnitRunner.class)
public class ServiceTests {
#InjectMocks
private UserInfoService UserInfoService;
#Mock
private UserInfoServiceClient UserInfoServiceClient;
#Test
public void shouldReturnUserInfoData() throws IOException{
final String userId = "123";
// The mocked return value should be set up per test scenario
final UserServiceDto dto = new UserServiceDto();
final ResponseEntity<UserServiceDTO> mockedResp = new ResponseEntity<>(dto, HttpStatus.OK);
// set up the mock service to return your response
when(UserInfoServiceClient.sendResponse(userId)).thenReturn(mockedResp);
// Call your service
ResponseEntity<ResponseUserInfoData> resp = UserInfoService.sendUserInfo(userId);
// Test the result
Assert.isNotNull(resp);
}
}
There are also other ways to mock the dependencies using Mockito. I suggest going through the quick start of https://site.mockito.org/

Getting blank response in spring rest controller unit test cases

I have written unit test cases for a spring rest controller for below put method
#PutMapping("/offers/{jobTitle}")
public Offer updateOffer(#PathVariable String jobTitle,#Valid #RequestBody Offer offer) {
return offerService.updateNoOfPost(jobTitle, offer);
}
Below is my service class
#Override
public Offer updateNoOfPost(String jobTitle, Offer offer) {
if(!offerRepository.existsById(jobTitle))
throw new ResourceNotFoundException("JobTitle "+jobTitle+" not found !!");
offer.setNoOfPost(offer.getNoOfPost());
return offerRepository.save(offer);
}
I have written the unit test case for this method using testNg and mockito
public class OfferControllerTest {
private MockMvc mvc;
private JacksonTester<Offer> jsonOffer;
#Mock
private OfferService service;
#InjectMocks
OfferController offerController;
private Offer offer;
#BeforeMethod
public void setup() {
offer = new Offer("LSE", new Date(),1);
MockitoAnnotations.initMocks(this);
mvc = MockMvcBuilders.standaloneSetup(offerController)
.build();
JacksonTester.initFields(this, new ObjectMapper());
}
#Test
public void updateOffer() throws Exception {
Mockito.when(service.updateNoOfPost("LSE", offer)).thenReturn(offer);
MockHttpServletResponse response = mvc.perform(
put("/offers/LSE").contentType(MediaType.APPLICATION_JSON).content(
jsonOffer.write(new Offer("SE", new Date(), 19)).getJson()
)).andReturn().getResponse();
assertThat(response.getContentAsString()).isEqualTo(new ObjectMapper().writeValueAsString(offer));
}
I am getting response code as 200. but getting blank body.pls find error below
FAILED: updateOffer
org.junit.ComparisonFailure: expected:<"[{"jobTitle":"LSE","createdAt":"2018-10-27","noOfPost":1}]"> but was:<"[]">
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
what am i missing ? is this the standard way of writting unit test cases for spring rest controller ?
Below mocking should fix the issue
Mockito.when(service.updateNoOfPost(Mockito.any(String.class), Mockito.any())).thenReturn(offer);
Read more here: stack-46914252

Cannot inject service into Spring test

financialReportService is null in REST controller that denotes it fails to inject.
Test:
#RunWith(SpringRunner.class)
#SpringBootTest(classes = SnapshotfindocApp.class)
public class FindocResourceIntTest {
#Inject
private FinancialReportService financialReportService;
#Before
public void setup() {
MockitoAnnotations.initMocks(this);
FindocResource findocResource = new FindocResource();
ReflectionTestUtils.setField(findocResource, "findocRepository", findocRepository);
this.restFindocMockMvc = MockMvcBuilders.standaloneSetup(findocResource)
.setCustomArgumentResolvers(pageableArgumentResolver)
.setMessageConverters(jacksonMessageConverter).build();
}
#Test
#Transactional
public void getFinancialRecords() throws Exception {
// Get all the financial-reports
restFindocMockMvc.perform(get("/api/financial-reports"))
.andExpect(status().isOk());
List<Findoc> finReports = financialReportService.getFinancialReports();
for (Findoc fr : finReports) {
assertThat(fr.getNo_months()).isBetween(12, 18);
LocalDate documentTimeSpanLimit = LocalDate.now().minusMonths(18);
assertThat(fr.getFinancial_date()).isAfterOrEqualTo(documentTimeSpanLimit);
}
}
The service:
#Service
#Transactional
public class FinancialReportService {
private final Logger log = LoggerFactory.getLogger(FinancialReportService.class);
#Inject
private FinancialReportDAO financialReportDAO;
public List<Findoc> getFinancialReports(){
return financialReportDAO.getFinancialReports();
}
}
Controller:
#GetMapping("/financial-reports")
#Timed
public List<Findoc> getFinancialReports() {
log.debug("REST request to get financial records");
return financialReportService.getFinancialReports(); // financialReportService is null
}
Update:
The application is generated by JHipster. Then the new service and DAO files were added to enable custom database queries to H2.
After #Injecting the service, you also need to set the field in the setup() method. Adding the below line should solve your problem
ReflectionTestUtils.setField(findocResource, "financialReportService", financialReportService);
On a separate note, the following part of the test looks weird. You are fetching the financial reports twice. This file is the FindocResourceIntTest, so I would remove any direct calls to financialReportService.
// Get all the financial-reports
restFindocMockMvc.perform(get("/api/financial-reports"))
.andExpect(status().isOk());
List<Findoc> finReports = financialReportService.getFinancialReports();

mocking nested function is giving NPE

Hi I am getting Null Pointer Exception while trying to write unit test cases
Here is the class detail:
public CreateDraftCampaignResponse createDraftCampaign(CreateDraftCampaignRequest request) throws InvalidInputsException,
DependencyException, UnauthorizedException {
CreateDraftCampaignResponse draftCampaignResponse = null;
try {
DraftCampaignDetails createdDraft = draftCampaignI.createDraftCampaign(ConvertionUtil
.getDraftCampaignDetailsfromCreateDraftRequest(request));
draftCampaignResponse = new CreateDraftCampaignResponse();
draftCampaignResponse.setDraftCampaignId(createdDraft.getDraftId());
}
catch (Exception e) {
log.error("Create Draft Campaign Exception", e);
throw e;
}
return draftCampaignResponse;
}
This is the ConvertionUtil class:
public static DraftCampaignDetails getDraftCampaignDetailsfromCreateDraftRequest(CreateDraftCampaignRequest request) {
DraftCampaignDetails draftCampaign = new DraftCampaignDetails();
DraftCampaignDetailsBase draftCampaignDetailsBase = request
.getDraftCampaignDetailsBase(); (This is giving exception)
draftCampaign.setCampaignBudget(draftCampaignDetailsBase
.getCampaignBudget());
draftCampaign.setCampaignName(draftCampaignDetailsBase
.getCampaignName());
draftCampaign.setDraftCampaignState(draftCampaignDetailsBase
.getDraftCampaignState());
draftCampaign.setCreatedUser(request.getUser());
draftCampaign.setObfuscatedEntityId(request.getObfuscatedEntityId());
draftCampaign.setCampaignInfo(request.getCampaignInfo());
return draftCampaign;
}
Thsi is what I tried:
#Test
public void createDraft_newDraft() {
DraftCampaignActivity draftContoller = new DraftCampaignActivity();
CreateDraftCampaignRequest request = createRequest();
DraftCampaignDetails details = buildDraftDetails();
if(draftCampaignI == null){
System.out.println("sccdscscd");
}
//ConvertionUtil action1 = PowerMockito.mock(ConvertionUtil.class);
//PowerMockito.when(action1.getDraftCampaignDetailsfromCreateDraftRequest(request)).thenReturn(details);
when(util.getDraftCampaignDetailsfromCreateDraftRequest(request)).thenReturn(details);
when(draftCampaignI.createDraftCampaign(details)).thenReturn(details);
CreateDraftCampaignResponse response = new CreateDraftCampaignResponse();
draftContoller.createDraftCampaign(request);
response.setDraftCampaignId(details.getDraftId());
Assert.assertEquals(response.getDraftCampaignId(),"ww");
}
I am getting NPE. I am a novice in Mockito and other framework. Please help!
It doesn't work because you try to mock a static method and you don't do it properly such that it calls the real method which leads to this NPE in your case.
To mock a static method using Powermock, you need to:
Use the #RunWith(PowerMockRunner.class) annotation at the class-level of the test case.
Use the #PrepareForTest(ClassThatContainsStaticMethod.class) annotation at the class-level of the test case.
Use PowerMock.mockStatic(ClassThatContainsStaticMethod.class) to mock all methods of this class.
So in your case, you should have something like:
#RunWith(PowerMockRunner.class)
public class MyTestClass {
#Test
#PrepareForTest(ConvertionUtil.class)
public void createDraft_newDraft() {
...
PowerMockito.mockStatic(ConvertionUtil.class);
PowerMockito.when(
ConvertionUtil.getDraftCampaignDetailsfromCreateDraftRequest(request)
).thenReturn(details);
...
}
More details about How to mock a static method with Powermock.

Categories