Cucumber StepDef ResultActions NullPointerException - java

I am receiving the following NullPointerException when trying to execute a Cucumber StepDefs file that passes a JSON from a .feature file to a REST endpoint on localhost;
I have tried to instantiate the ResultActions in every other way, receiving the same error.
The Controller works linked to the test is fine, and is pointing to the correct REST endpoint.
The issue is with the result in personStepDefs
I don't think I'm missing a parameter for ResultActions result as I've built my RequestBuilder
java.lang.NullPointerException at com.///.v2.PersonStepDefs.i\_add\_a\_new\_Person\_using\_POST\_at\_with\_JSON([PersonStepDefs.java:49](https://PersonStepDefs.java:49)) at
✽.I add a new Person using POST at "[http://localhost:8080/services/person/add](http://localhost:8080/services/person/add)" with JSON:(file:///C:/path/to/src/test/resources/Person.feature:6)
PersonStepDefs.java
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import org.junit.BeforeClass;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
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.ResultActions;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.context.WebApplicationContext;
import io.cucumber.java.en.Then;
import io.cucumber.java.en.When;
#RunWith(SpringJUnit4ClassRunner.class)
#WebAppConfiguration
#Transactional
/**
* Person Step Definition class to execute Scenario contained in Person.feature
* #author Lewis Jones
*
*/
public class PersonStepDefs {
#Autowired
private volatile WebApplicationContext wac;
#Autowired
private volatile MockMvc mockMvc;
private ResultActions result;
/**
* Runs the application server before every scenario.
*/
#BeforeClass
public void setup() {
this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build();
}
#When("I add a new Person using POST at {string} with JSON:")
public void i_add_a_new_Person_using_POST_at_with_JSON(String request, String json) throws Exception {
result = mockMvc.perform(post(request).contentType(MediaType.APPLICATION_JSON)
.content(json.getBytes()));
}
#Then("the response code should be {int}")
public void the_response_code_should_be(Integer responseCode) throws Exception {
result.andExpect(status().is(responseCode));
}
}
RunMvcTest.java
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.web.WebAppConfiguration;
import io.cucumber.junit.Cucumber;
import io.cucumber.junit.CucumberOptions;
#RunWith(Cucumber.class)
#CucumberOptions(
plugin = {"pretty","html:build/cucumber-html-report"},
features = "src/test/resources", strict = true)
#WebAppConfiguration
#ContextConfiguration(classes = V2Application.class)
/**
* A class to run the Cucumber .feature files located in 'features'
* #author Lewis Jones
*
*/
public class RunMvcTest {
}
Person.feature
Feature: Person CRUD
As a User, I want to add a Person
#repo
Scenario: Person.Repo.Add
When I add a new Person using POST at "http://localhost:8080/services/person/add" with JSON:
"""
{"firstName":"Lewis","lastName":"Jones","addressId":"1", "dob":"1999-07-11"}
"""
Then the response code should be 200

A null pointer exception happens when you try to de-reference a variable or field that is null. So if you try to call perform on mockMvc while mockMvc is null you will get a null pointer exception.
If you read the stack trace carefully you can see that this it what it tries to tell you.
result = mockMvc.perform(....);
So how can mockMcv be null? You initialize it in setup method right? That means setup isn't called. You can confirm this by putting a break point in the method and debugging your test.
import org.junit.BeforeClass;
....
/**
* Runs the application server before every scenario.
*/
#BeforeClass
public void setup() {
this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build();
}
And setup doesn't get called because BeforeClass is a JUnit annotation. Cucumber uses io.cucumber.java.Before.

Related

Spring boot WebMvcTest cases keep getting terminated and won't run

When I try using the below code to test the controllers no errors happen, it just says terminated with no logged messages or anything.
import static org.junit.Assert.assertEquals;
import java.util.Arrays;
import java.util.List;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.test.web.servlet.RequestBuilder;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import ....controllers.UserController;
import ....data.response.UserResponse;
import ....models.user.User;
#RunWith(SpringRunner.class)
#WebMvcTest(UserController.class)
public class UserWebMvc {
#Autowired
private MockMvc mvc;
#Test
public void givenEmployees_whenGetEmployees_thenReturnJsonArray() throws Exception {
User alex = new User();
List<UserResponse> allUsers = Arrays.asList(new UserResponse(alex.getId(), alex.getInfo()));
RequestBuilder request = MockMvcRequestBuilders.get("/hello");
MvcResult result = mvc.perform(request).andReturn();
assertEquals(result.getResponse().getContentAsString(), "hello");
// userService.createUser(
// new UserRequest(alex.getInfo().getName(), alex.getInfo().getEmail(), alex.getInfo().getPassword()));
//
}
}
However my test to check that junit is working runs fine, so I'm thinking its something to do with SpringRunner or WebMvc
#SpringBootTest
class BackendApplicationTests {
#Test
void contextLoads() {
assertTrue(false);
}
}
Isn't assertTrue(false) always going to be false? You are basically checking whether false equals true, which will always fail.
Also, from the Spring documentation regarding #WebMvcTest:
Using this annotation will disable full auto-configuration and instead apply only configuration relevant to MVC tests (i.e. #Controller, #ControllerAdvice, #JsonComponent, Converter/GenericConverter, Filter, WebMvcConfigurer and HandlerMethodArgumentResolver beans but not #Component, #Service or #Repository beans).
Using this annotation, it will not scan any beans from the service layer. So if you have a UserService which is injected into the UserController, it will not be found by Spring.
When I run tests like this, I would do something like:
class UserControllerTest {
#InjectMocks
private UserController userController;
private MockMvc mockMvc;
#BeforeEach
public void setUp() {
MockitoAnnotations.openMocks(this);
mockMvc =
MockMvcBuilders.standaloneSetup(userController).build();
}
#Test
public void givenEmployees_whenGetEmployees_thenReturnJsonArray()
throws Exception {
User alex = new User();
List<UserResponse> allUsers = Arrays.asList(new
UserResponse(alex.getId(), alex.getInfo()));
RequestBuilder request = MockMvcRequestBuilders.get("/hello");
MvcResult result = mvc.perform(request).andReturn();
assertEquals(result.getResponse().getContentAsString(),
"hello");
}
}
I was using the wrong import. Changing to this fixed it
import static org.junit.Assert.assertTrue;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

Make my #Test GET request work in Spring Boot

beginner here. I have created an API in Spring Boot using java and I want to test whether the GET request returns a 200. I'm not interested in checking what's returned (a JSON object) I just want to check whether this connection works. I have tried this code so far:
#Test
void getRequest() throws Exception {
// this doesn't work because a ResultMatcher is needed
this.mvc.perform(get("/currencies")).andExpect(HttpStatus.ACCEPTED);
//tried this too and I get "Cannot resolve method 'assertThat(int, int)'"
RequestBuilder request = get("/currencies");
MvcResult result = mvc.perform(request).andReturn();
assertThat(result.getResponse().getStatus(), 200);
}
On the first statement, I'm literally saying "do a get request for this base url and expect a http accepted status" it isn't liking it. Am I asking for too much?
my second attempt I'm saying "Make a MvcResult object and store the result of the GET request within it. Then compare it to the status code of 200"
Here is the full class
import com.example.CoinAPI.controller.CoinController;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.http.HttpStatus;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.test.web.servlet.RequestBuilder;
import static org.assertj.core.api.Assertions.assertThat;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
#AutoConfigureMockMvc
#SpringBootTest
class CoinApiApplicationTests {
#Autowired
private CoinController controller;
#Autowired
private MockMvc mvc;
#Test
void contextLoads() {
assertThat(controller).isNotNull();
}
#Test
void getRequest() throws Exception {
// this doesn't work
this.mvc.perform(get("/currencies")).andExpect(HttpStatus.ACCEPTED);
//tried this too
RequestBuilder request = get("/currencies");
MvcResult result = mvc.perform(request).andReturn();
assertThat(result.getResponse().getStatus(), 200);
}
}
How do I make this work? I have searched endlessly around Google and youtube. nothing is helping me. I am missing something, I am sure

NullPointerException while injecting mock in PowerMock

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);

JUnit Test cases Run with tomcat container or JVM

I am writing JUnit test cases for my spring application. I use codepro tool in eclipse for generate test cases. when I run this test cases than it is run on JVM not on Tomcat server. so I want to know how it could be run on server? and which is best practice to run test cases on JVM or tomcat? and why? so please suggest me. code is as follow.
import java.io.InputStream;
import java.util.Properties;
import javax.servlet.http.HttpSession;
import junit.framework.TestCase;
import junit.framework.TestSuite;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpSession;
import org.springframework.stereotype.Controller;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.web.bind.annotation.RequestMapping;
import com.zodiacapi.framework.business.ZodiacMobileBusinessTx;
import com.zodiacapi.framework.controller.ZodiacMobileAPIController;
import com.zodiacapi.framework.delegate.SendNotificationDelegate;
import com.zodiacapi.framework.dto.ReturnAPIMessageDTO;
import com.zodiacapi.framework.dto.UserDTO;
import com.zodiacweb.framework.cache.CacheService;
import com.zodiacweb.framework.cache.EhCacheServiceImpl;
import com.zodiacweb.framework.exception.ZodiacWebException;
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration({ "classpath:applicationContext.xml" })
public class ZodiacMobileAPIControllerTest extends TestCase {
private static final Logger logger = LoggerFactory.getLogger(ZodiacMobileAPIControllerTest.class);
#Autowired
private ZodiacMobileBusinessTx zodiabMobileBusinessTx;
public ZodiacMobileBusinessTx getZodiabMobileBusinessTx() {
return zodiabMobileBusinessTx;
}
#Test
public void testMobileLogin_1()
throws Exception {
ReturnAPIMessageDTO entities = new ReturnAPIMessageDTO();
Properties prop = new Properties();
InputStream in = getClass().getResourceAsStream("login.properties");
prop.load(in);
try{
UserDTO result = zodiabMobileBusinessTx.login(prop.getProperty("username"), prop.getProperty("password"), prop.getProperty("apikey"), prop.getProperty("deviceid"), prop.getProperty("deviceModel"));
System.out.println("result of test"+result);
} catch (ZodiacWebException e) {
logger.error("Internal Server Error fetching user info", e);
entities.setStatus("false");
entities.setMessage(e.getMessage());
entities.setVersion("");
} catch (Throwable t) {
entities.setStatus("false");
entities.setMessage(t.getMessage());
entities.setVersion("");
}
}
}
For a unit test you would usually execute it within the JVM. You would probably only execute Integration/Functional tests on an application running in a server.
The choices you have for testing a Spring Controller(That I am familiar with) are:
Test the controller as a regular POJO outside of the container and server
for example : MyController controller = new MyController())
Test the controller using Spring Test MVC. This will actually start up Spring during your tests.(I prefer this option) see Unit Test Spring Controllers for some examples.
If you want to test your application in a real tomcat instance you can use
Arquillian together with The Arquillian Spring Extension. This last option is definitely the most complex in terms of learning curve. But it's nice to be aware of.(Haven't successfully used it with a Spring Application myself)
Don't worry about using Arquillian for now ... it takes some time to learn.
See my code below for a working example of testing a spring controller. I noticed from your code sample that you did not have all the correct annotations and the initialization method.
#RunWith(SpringJUnit4ClassRunner.class)
#SpringApplicationConfiguration(classes = App.class)
#TestPropertySource(locations = "classpath:test.properties")
#WebAppConfiguration
public class AdminUserControllerUnitTest {
MockMvc mvc;
#Autowired
WebApplicationContext webApplicationContext;
#Before
public void initialize(){
mvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build();
}
#Test
public void testListUsers() throws Exception {
Account account = new Account();
account.setId(1l);
mvc.perform(
get("/admin/user")
.sessionAttr("account",account)
);
.andExpect(MockMvcResultMatchers.model().attribute("users",hasSize(4)));
}

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?

Categories