NullPointerException while injecting mock in PowerMock - java

I am trying to mock private method inside singleton bean. Test class looks like:
import static org.mockito.Matchers.anyObject;
import static org.mockito.Mockito.when;
import java.util.Hashtable;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
#RunWith(PowerMockRunner.class)
#PrepareForTest(SampleBean.class)
public class SampleBeanTest{
#InjectMocks
private SampleBean sampleBean = new SampleBean();
/**
* Sets the up.
* #throws Exception the exception
*/
#Before
public final void setUp() throws Exception {
//MockitoAnnotations.initMocks(SampleBean);
PowerMockito.doReturn("response").when(sampleBean, "privateMethod", anyObject(), DUMMY_QUEUE);
}
#Test
public void testGetData() throws Exception {
sampleBean.publicMethod();
}
}
When I run test, I get exception as:
java.lang.NullPointerException: null
at org.powermock.api.mockito.internal.expectation.PowerMockitoStubberImpl.addAnswersForStubbing(PowerMockitoStubberImpl.java:68)
at org.powermock.api.mockito.internal.expectation.PowerMockitoStubberImpl.prepareForStubbing(PowerMockitoStubberImpl.java:123)
at org.powermock.api.mockito.internal.expectation.PowerMockitoStubberImpl.when(PowerMockitoStubberImpl.java:91)
at com.temp.SampleBeanTest.setUp(SampleBeanTest.java:30)
I found out that PowerMock returns null at line:
MockitoMethodInvocationControl invocationControl = (MockitoMethodInvocationControl) MockRepository.getInstanceMethodInvocationControl(mock);
I am not sure what is the reason behind this weird behavior. Please let me know, if you have any idea.

It looks like sampleBean is null.
You need the MockitoAnnotations.initMocks call that is commented-out, but like this:
MockitoAnnotations.initMocks(this);
Or, doing it manually:
sampleBean = mock(SampleBean.class);

Related

Why does #InjectMocks in Java Spring return null in my test case for a service?

I am trying to write test cases for a service I have implemented for a controller in Spring. I have the following Service and Test classes.
StudentCourseRequestService:
import java.util.List;
import org.springframework.stereotype.Service;
import model.CourseRequest;
import repository.ICourseRequestRepository;
import lombok.RequiredArgsConstructor;
#Service
#RequiredArgsConstructor
public class StudentCourseRequestService implements IStudentCourseRequestService {
private final ICourseRequestRepository courseRequestRepository;
#Override
public boolean requestCourse(CourseRequest courseRequest) {
return courseRequestRepository.saveRequest(courseRequest);
}
#Override
public List<CourseRequest> getAllCourseRequests() {
return courseRequestRepository.getAllCourseRequests();
}
#Override
public List<CourseRequest> getAllCourseRequestsOfStudent(Long studentId) {
return courseRequestRepository.getCourseRequestsByStudentId(studentId);
}
}
Test class:
import org.junit.jupiter.api.Test;
import org.mockito.InjectMocks;
import org.mockito.Mockito;
import org.springframework.boot.test.mock.mockito.MockBean;
import static org.assertj.core.api.Assertions.assertThat;
import model.CourseRequest;
import repository.ICourseRequestRepository;
public class StudentCourseRequestServiceTests {
#MockBean
private ICourseRequestRepository courseRequestRepository;
#InjectMocks
private StudentCourseRequestService studentCourseRequestService;
#Test
public void requestValidCourse() throws Exception {
final CourseRequest courseRequest = new CourseRequest(
"data0",
"data1",
"data2",
"data3",
"data4",
"data5"
);
Mockito.when(courseRequestRepository.saveRequest(courseRequest)).thenReturn(true);
boolean result = studentCourseRequestService.requestCourse(courseRequest);
assertThat(result).isTrue();
}
}
When I run the requestValidCourse() test case, I get the following error:
java.lang.NullPointerException: Cannot invoke "repository.ICourseRequestRepository.saveRequest(model.CourseRequest)" because "this.courseRequestRepository" is null
at service.StudentCourseRequestServiceTests.requestValidCourse(StudentCourseRequestServiceTests.java:29)
at java.base/java.util.ArrayList.forEach(Unknown Source)
at java.base/java.util.ArrayList.forEach(Unknown Source)
How can I resolve this issue?
As #Lesiak recommended, I added the #ExtendWith(MockitoExtension.class) annotation to the top of the class, and changed courseRequestRepository to have the #Mock annotation, instead of the previous #MockBean annotation. The issue got resolved after these changes.
Previously I had the configuration recommended by #Lesiak during my trials to resolve the issue, but I also had the annotation #ExtendWith(SpringExtension.class) at the top of the class. With this configuration, I got the same error. Removing the #ExtendWith(SpringExtension.class) annotation resolved the issue here.
New test class:
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.junit.jupiter.MockitoExtension;
import static org.assertj.core.api.Assertions.assertThat;
import model.CourseRequest;
import repository.ICourseRequestRepository;
#ExtendWith(MockitoExtension.class)
public class StudentCourseRequestServiceTests {
#Mock
private ICourseRequestRepository courseRequestRepository;
#InjectMocks
private StudentCourseRequestService studentCourseRequestService;
#Test
public void requestValidCourse() throws Exception {
final CourseRequest courseRequest = new CourseRequest(
"data0",
"data1",
"data2",
"data3",
"data4",
"data5"
);
Mockito.when(courseRequestRepository.saveRequest(courseRequest)).thenReturn(true);
boolean result = studentCourseRequestService.requestCourse(courseRequest);
assertThat(result).isTrue();
}
}

Why we need to mock static class before every test case in same class

I have a test class with two test cases . I am using Junit 4. My these test cases are using static class. So I mocked a static class in #BeforeClass method so that it is only mocked once before the start of execution of test cases. but in this case only first test case works fine and rest of all test cases fails. so for that I mocked my static class in #Before method so that it is been mocked before every test case execution. So I want to understand that why is there need to mock the static class before every test case and why cant we mock it only once before start of execution of class.
import com.walmart.fulfillment.encryption.logging.HttpThreadBusinessContext;
import com.walmart.rxorderdetailsfulfillment.data.LabelOverFlowOrderRepo;
import com.walmart.rxorderdetailsfulfillment.models.entity.LabelOverFlowOrder;
import com.walmart.rxorderdetailsfulfillment.models.entity.LabelOverFlowPK;
import com.walmart.rxorderdetailsfulfillment.models.request.LabelOverFlowRequest;
import com.walmart.rxorderdetailsfulfillment.models.response.LabelOverFlowResponse;
import com.walmart.rxorderdetailsfulfillment.util.LabelOverFlowUtility;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import static org.junit.Assert.*;
import static org.mockito.Mockito.when;
#RunWith(PowerMockRunner.class)
#PrepareForTest({LabelOverFlowUtility.class,HttpThreadBusinessContext.class,LabelOverFlowOrderRepo.class,LabelOverFlowResponse.class,LabelOverFlowOrder.class,LabelOverFlowPK.class})
public class LabelOverFlowRequestHandlerTest {
static int count =0;
LabelOverFlowRequest labelOverFlowRequest;
#InjectMocks
LabelOverFlowRequestHandler labelOverFlowRequestHandler;
#Mock
HttpThreadBusinessContext httpThreadBusinessContext;
#Mock
LabelOverFlowOrderRepo labelOverFlowOrderRepo;
#Mock
LabelOverFlowResponse labelOverFlowResponse;
#Mock
LabelOverFlowOrder labelOverFlowOrder;
#Mock
LabelOverFlowPK labelOverFlowPK;
#BeforeClass
public static void initialization(){
//PowerMockito.mockStatic(LabelOverFlowUtility.class);
}
#Before
public void initialization_Before_Every_Test(){
PowerMockito.mockStatic(LabelOverFlowUtility.class);
labelOverFlowRequest = LabelOverFlowRequest.builder().textOverFlow(true).warningOverFlow(true).rxFillId(555).siteNbr(5550).countryCode("US").build();
}
/**
* This test case is use to check success is returned after saving data to DB.
*/
#Test
public void processSaveLabelOverFlowResquestWithSuccess() {
when(LabelOverFlowUtility.getLabelOverFlowPK(Mockito.any())).thenReturn(labelOverFlowPK);
when(LabelOverFlowUtility.getLabelOverFlowOrder(Mockito.any())).thenReturn(labelOverFlowOrder);
when(labelOverFlowOrderRepo.save(Mockito.any())).thenReturn(labelOverFlowResponse);
when(LabelOverFlowUtility.getLabelOverFlowResponse(Mockito.any())).thenCallRealMethod();
Mockito.doReturn(labelOverFlowOrder).when(labelOverFlowOrderRepo).save(Mockito.any());
assertTrue(labelOverFlowRequestHandler.processSaveLabelOverFlowResquest(labelOverFlowRequest).getResponseText().equals("success"));
}
/**
* This test case is ued to check if data is not saved to DB
*/
#Test
public void processSaveLabelOverFlowResquestWithFailure() {
when(LabelOverFlowUtility.getLabelOverFlowPK(Mockito.any())).thenReturn(labelOverFlowPK);
when(LabelOverFlowUtility.getLabelOverFlowOrder(Mockito.any())).thenReturn(labelOverFlowOrder);
when(labelOverFlowOrderRepo.save(Mockito.any())).thenReturn(labelOverFlowResponse);
when(LabelOverFlowUtility.getLabelOverFlowResponse(Mockito.any())).thenCallRealMethod();
Mockito.doThrow(new RuntimeException()).when(labelOverFlowOrderRepo).save(Mockito.any());
assertTrue(labelOverFlowRequestHandler.processSaveLabelOverFlowResquest(labelOverFlowRequest).getResponseText().equals("failure"));
}
}
LabelOverFlowUtility.class is a static class, there should be no need to mock it at all if the methods are deterministic(given same input same thing happens).
I may be misunderstanding how this class operates.

Unit tests in Spring MVC Rest - cast issue

I am developing simple Rest API app and trying to test it using this tutorial: http://memorynotfound.com/unit-test-spring-mvc-rest-service-junit-mockito/
I have implemented entire test_get_all_success unit test using my working Rest API (written in Spring MVC). Unfortunately test cannot run because of following issue.
Here is entire test file:
import java.util.Arrays;
import static org.mockito.Mockito.when;
import static org.springframework.test.web.client.match.MockRestRequestMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.test.web.servlet.MockMvc;
import static org.hamcrest.Matchers.*;
import org.junit.Before;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import static org.mockito.Mockito.*;
import org.mockito.MockitoAnnotations;
import org.springframework.http.MediaType;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(classes={MyConfigClass.class})
#WebAppConfiguration
public class ClientTest {
private MockMvc mockMvc;
#Mock
private ClientManagerImpl clientManager;
#InjectMocks
private ClientController clientController;
#Before
public void init(){
MockitoAnnotations.initMocks(this);
mockMvc = MockMvcBuilders
.standaloneSetup(clientController)
.build();
}
#Test
public void findAll_ClientsFound_ShouldReturnFoundClients() throws Exception {
Client a = ...;
Client b = ...;
when(clientManager.getClients()).thenReturn(Arrays.asList(a, b));
mockMvc.perform(get("/clients"))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8_VALUE))
.andExpect(jsonPath("$", hasSize(2)));
verify(clientManager, times(1)).getClients();
verifyNoMoreInteractions(clientManager);
}
}
NetBeans shows error in this line:
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8_VALUE))
incompatible types: RequestMatcher cannot be converted to ResultMatcher
Test cannot run because of this error. When I delete this line everything works fine and test is passed.
What am I doing wrong?
The following static import causes the conflict:
import static org.springframework.test.web.client.match.MockRestRequestMatchers.content;
MockRestRequestMatchers class is used for client-side REST testing using MockRestServiceServer, but you are testing here MVC application controllers.

JUnit Mockito Request and Response

I am trying to create a test for a login page using JUnit where I need to mock out dev controller.
As I used a HttpServlet in my dev environment, for testing environment it is asking for httprequest...
I went for Mock request where my file is not getting where I'm using a controller not a servlet.
Can anyone help me on this?
Below is my JUnit Controller
package com.atoc.test.controller;
import java.io.PrintWriter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.redirectedUrl;
import static org.junit.Assert.assertNotNull;
import static org.mockito.Mockito.when;
import com.atoc.test.DAO.UserTestDAO;
import com.atoc.test.service.UserTestService;
import com.bpa.qaproduct.controller.UserController;
import com.bpa.qaproduct.entity.User;
import com.bpa.qaproduct.service.UserService;
import org.apache.commons.io.FileUtils;
#RunWith(SpringJUnit4ClassRunner.class)
#WebAppConfiguration
#ContextConfiguration(locations = { "classpath:testApplicationContext.xml" })
public class UserControllerTest{
#Mock
private UserService userService;
#Mock
private HttpServletRequest request;
#Mock
private HttpServletResponse response;
#InjectMocks
private UserController userController;
private MockMvc mockMvc;
#Before
public void setup() {
MockitoAnnotations.initMocks(this);
mockMvc = MockMvcBuilders.standaloneSetup(userController).build();
}
#Test
public void testviewUserrList() throws Exception {
User user = new User();
//int value = null;
when(userService.getUserFilterCount(user)).thenReturn(20);
//mockMvc.perform(get("/todo/"));
mockMvc.perform(get("/user/viewUserList")).andExpect(status().isOk());
}
#Test
public void testloginVerification() throws Exception
{
User user = new User();
HttpServletRequest request = Mockito.mock(HttpServletRequest.class);
HttpServletResponse response = Mockito.mock(HttpServletResponse.class);
when(request.getParameter("userName")).thenReturn("me");
when(request.getParameter("password")).thenReturn("secret");
mockMvc.perform(post("/user/loginVerification"))
.andExpect(status().isOk());
System.out.println("***********"+request.getParameter("userName"));
}
}
The test case does not pass and httprequest is not passing values.
So I'm getting a NullPointerException in my running environment
I mocked out the request and response methods but I'm still getting the same error.
Passing value is not null
I'm giving some values there
setting time might be the problem
I didn't extend any Mockito in main class where I'm using inner methods
You have to provide request parameters to mockmvc instead of a request object.
#Test
public void testloginVerification() throws Exception {
User user = new User();
mockMvc.perform(post("/user/loginVerification")
.param("userName", "me")
.param("password", "secret"))
.andExpect(status().isOk());
}
Also the User object is not interacting with the other code of your test. I think you're doing something completely wrong. Can you add the code of the UserController?

Why isn't PowerMockito mocking this class properly?

I am using PowerMockito and this is my test:
import com.PowerMockitoProduction;
import org.apache.commons.httpclient.HttpClient;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
#RunWith(PowerMockRunner.class)
#PrepareForTest(HttpClient.class)
public class PowerMockitoTest {
#Test(expected = UnsupportedOperationException.class)
public void test() throws Exception {
PowerMockito.whenNew(HttpClient.class).withNoArguments().thenThrow(new UnsupportedOperationException());
new PowerMockitoProduction().createClient();
}
}
This test is failing.
java.lang.AssertionError: Expected exception: java.lang.UnsupportedOperationException
Here's what PowerMockitoProduction does:
package com;
import org.apache.commons.httpclient.HttpClient;
public class PowerMockitoProduction {
public void createClient() {
HttpClient client = new HttpClient();
System.out.println(client);
}
}
I expect this code to create a mock HttpClient based on this line in my test:
PowerMockito.whenNew(HttpClient.class).withNoArguments().thenThrow(new UnsupportedOperationException());
But it doesn't seem to be effecting my production code. What am I doing wrong?
I figured out what I was doing wrong. I need to change:
#PrepareForTest(HttpClient.class)
to
#PrepareForTest(PowerMockitoProduction.class)

Categories