java.lang.NullPointerException while testing RESTful Api with jUnit - java

I am trying to write a test case for following controller code using JUnit.
But I am getting 500 code with null pointer Exception. (When I test this on Postman, it works without any exception.) I think HttpServeleRequest Request of validEmp might cause this null pointer exception to testGetMethod. Can any one please tell what I am doing wrong here and how to fix this? Thank you for your help:D
LoginService
public ReturnParam validEmp(HttpServletRequest request, String locale, String empKey, String accessToken) throws Exception {
ReturnParam rp = new ReturnParam();
rp.setFail("not available");
return rp;
}
LoginController
#RequestMapping(value = "/valid", method = RequestMethod.GET, produces = "application/json; charset=UTF-8")
public #ResponseBody ReturnParam validEmp(HttpServletRequest request,
#RequestParam(value = "locale", required = true) String locale,
#RequestParam(value = "empKey", required = true) String empKey,
#RequestParam(value = "accessToken", required = true) String accessToken) throws Exception {
return service.validEmp(request, locale, empKey, accessToken);
}
LoginControllerTest
public MockMvc mockMvc;
private MediaType contentType = new MediaType(MediaType.APPLICATION_JSON.getType(),
MediaType.APPLICATION_JSON.getSubtype(), Charset.forName("utf8"));
public void testGetMethod(String url, String locale, String empKey, String acessToken) throws Exception {
mockMvc.perform(get(url).param("locale", locale).param("empKey",empKey).param("accessToken", acessToken))
.andDo(print())
.andExpect(status().isOk());
}
Console
java.lang.NullPointerException
at com.isu.ifm.hr.control.LoginController.validEmp(LoginController.java:69)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:221)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:137)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:110)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:776)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:705)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:959)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:893)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:966)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:857)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:687)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:842)
at org.springframework.test.web.servlet.TestDispatcherServlet.service(TestDispatcherServlet.java:65)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:790)
at org.springframework.mock.web.MockFilterChain$ServletFilterProxy.doFilter(MockFilterChain.java:167)
at org.springframework.mock.web.MockFilterChain.doFilter(MockFilterChain.java:134)
at org.springframework.test.web.servlet.MockMvc.perform(MockMvc.java:144)
at com.isu.ifm.HttpMethodUnitTest.testGetMethod(HttpMethodUnitTest.java:21)
at com.isu.ifm.testcase.LoginControllerTest.TestCaseMain(LoginControllerTest.java:38)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:73)
at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:82)
at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:73)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:224)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:83)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:68)
at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:163)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:89)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:41)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:541)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:763)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:463)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:209)
MockHttpServletRequest:
HTTP Method = GET
Request URI = /certificate/valid
Parameters = {locale=[ko_KR], empKey=[ISU_ST#18017], accessToken=[]}
Headers = {}
Handler:
Type = com.isu.ifm.hr.control.LoginController
Method = public com.pb.common.vo.ReturnParam com.isu.ifm.hr.control.LoginController.validEmp(javax.servlet.http.HttpServletRequest,java.lang.String,java.lang.String,java.lang.String) throws java.lang.Exception
Async:
Async started = false
Async result = null
Resolved Exception:
Type = java.lang.NullPointerException
ModelAndView:
View name = jsonView
View = null
Attribute = status
value = FAIL
Attribute = message
value = null
FlashMap:
MockHttpServletResponse:
Status = 500
Error message = null
Headers = {}
Content type = null
Body =
Forwarded URL = jsonView
Redirected URL = null
Cookies = []
INFO : org.springframework.context.support.GenericApplicationContext - Closing org.springframework.context.support.GenericApplicationContext#5abca1e0: startup date [Thu Nov 01 16:46:45 KST 2018]; root of context hierarchy
INFO : org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor - Shutting down ExecutorService 'taskExecutor'

You need to mock your LoginService in LoginController. Try to add such code to LoginControllerTest.
#Mock
private LoginService loginService;
#InjectMocks
private LoginController loginController;
#Before
public void init(){
MockitoAnnotations.initMocks(this);
mockMvc = MockMvcBuilders
.standaloneSetup(loginController)
.build();
}

I think problem ist not a request , but injection. According your stacktrace I would say, that service is null (injection in controller isn't working)

Related

Assertion Error while testing rest controller Expected :200 Actual :404

I'm trying to test my simple rest controller method to get all offers but i always get java.lang.AssertionError: Status Expected :200 Actual :404. I don't know if there is problem with mocking or finding my component. I was trying to find solution in other posts but none of them was matching to my problem. Any ideas?
My Service:
#Service
#Transactional
class OfferServiceImpl implements OfferService {
private OfferRepository offerRepository;
#Autowired
public OfferServiceImpl(OfferRepository offerRepository) {
this.offerRepository = offerRepository;
}
#Override
public List<Offer> getAll(){
return (List<Offer>) offerRepository.findAll();
}
My Controller:
#RestController
#RequestMapping("/api/offers")
class OfferRestController {
private OfferService offerService;
#Autowired
public OfferRestController(OfferService offerService) {
this.offerService = offerService;
}
#GetMapping
List<Offer> getAllOffers(){
return offerService.getAll();
}
My Test Class:
#RunWith(SpringRunner.class)
#WebMvcTest(value = OfferRestController.class)
public class OfferControllerIntegrationTest {
private Offer offer1;
private Offer offer2;
#MockBean
private OfferService offerServiceMock;
#Autowired
private WebApplicationContext webApplicationContext;
#Autowired
private MockMvc mvc;
#Before
public void setUpOffers(){
offer1 = new Offer("Java Dev",
4000,
5000,
"CEO",
"Java",
"Lorem ipsum",
"user#gmail.com",
true);
offer2 = new Offer("PHP Dev",
4000,
5000,
"CEO",
"PHP",
"Lorem ipsum",
"user#gmail.com",
true);
}
#Before
public void setUp() {
this.mvc = standaloneSetup(new OfferRestController(offerServiceMock))
.alwaysExpect(MockMvcResultMatchers.content()
.contentType("application/json;charset=UTF-8"))
.defaultRequest(get("/").accept(MediaType.APPLICATION_JSON))
.alwaysExpect(status().isOk())
.build();
this.mvc = MockMvcBuilders.webAppContextSetup(webApplicationContext)
.alwaysDo(print())
.build();
}
#Test
public void givenOffers_whenGetOffers_thenReturnJsonArray() throws Exception{
List<Offer> allOffers= Arrays.asList(offer1,offer2);
given(offerServiceMock.getAll()).willReturn(allOffers);
mvc.perform(get("/api/offers")
.contentType(MediaType.APPLICATION_JSON))
.andExpect(status().isOk())
.andExpect(jsonPath("$",hasSize(2)))
.andExpect(jsonPath("$[0].name").value(offer1.getName()))
.andExpect(jsonPath("$[1].name").value(offer2.getName()))
.andDo(print());
verify(offerServiceMock,times(1)).getAll();
verifyNoMoreInteractions(offerServiceMock);
}
}
My App:
#SpringBootApplication
#EntityScan(basePackageClasses = {App.class, Jsr310JpaConverters.class})
#ComponentScan({"com"})
public class App {
public static void main(String[] args) {
SpringApplication.run(App.class, args);
}
}
And my problem:
MockHttpServletRequest:
HTTP Method = GET
Request URI = /api/offers
Parameters = {}
Headers = {Content-Type=[application/json]}
Body = <no character encoding set>
Session Attrs = {}
Handler:
Type =
org.springframework.web.servlet.resource.ResourceHttpRequestHandler
Async:
Async started = false
Async result = null
Resolved Exception:
Type = null
ModelAndView:
View name = null
View = null
Model = null
FlashMap:
Attributes = null
MockHttpServletResponse:
Status = 404
Error message = null
Headers = {}
Content type = null
Body =
Forwarded URL = null
Redirected URL = null
Cookies = []
java.lang.AssertionError: Status
Expected :200
Actual :404
<Click to see difference>
at org.springframework.test.util.AssertionErrors.fail(AssertionErrors.java:55)
at org.springframework.test.util.AssertionErrors.assertEquals(AssertionErrors.java:82)
at org.springframework.test.web.servlet.result.StatusResultMatchers.lambda$matcher$9(StatusResultMatchers.java:619)
at org.springframework.test.web.servlet.MockMvc$1.andExpect(MockMvc.java:178)
at brozek.com.offer.OfferControllerIntegrationTest.givenOffers_whenGetOffers_thenReturnJsonArray(OfferControllerIntegrationTest.java:89)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.springframework.test.context.junit4.statements.RunBeforeTestExecutionCallbacks.evaluate(RunBeforeTestExecutionCallbacks.java:73)
at org.springframework.test.context.junit4.statements.RunAfterTestExecutionCallbacks.evaluate(RunAfterTestExecutionCallbacks.java:83)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75)
at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86)
at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:251)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:97)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:190)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
Usually integration test setup should mock the controller created in the test Spring context with #WebMvcTest(value = OfferRestController.class). The usual syntax is:
#RunWith(SpringRunner.class)
#WebMvcTest(value = OfferRestController.class)
#AutoConfigureMockMvc
public class OfferRestControllerTest {
#MockBean
private OfferService offerService;
#Autowired
private MockMvc mvc;
}
In your test it's pointless to set Content-Type on GET request which has no body, remove
.contentType(MediaType.APPLICATION_JSON)
Starting from Spring 4.1 it's not necessary to use #Autowired on single constructor. You can simplify your code by removing #Autowired here:
public OfferServiceImpl(OfferRepository offerRepository) {
this.offerRepository = offerRepository;
}

Test endpoint with HTTP GET

I would like to test the endpoint if the response and HTTP code are correct. The controller method looks like this:
#CrossOrigin
#RequestMapping(method = RequestMethod.GET, value = "/{ruleId}")
public Rule loadOneRule(#PathVariable String ruleId) {
return rulesService.loadOneRule(ruleId);
}
The test method is
#Test
public void loadOneRule() throws IOException, URISyntaxException {
NodeDTO nodeDto = new NodeDTO();
HashMap<String, NodeDTO> nodes = new HashMap<>();
nodes.put("foo", nodeDto);
Rule rule = new Rule("my rule", nodes);
RuleService ruleService = new RuleService();
rule = ruleService.saveRule(rule);
String id = rule.getId().toString();
String target = "http://localhost:8090" + "/v2/rules/" + id;
URI uri = new URI(target);
HttpGet httpGet = new HttpGet(uri.toASCIIString());
HttpResponse response = httpClient.execute(httpGet);
int HTTPcode = response.getStatusLine().getStatusCode();
HttpEntity entity = response.getEntity();
String json = EntityUtils.toString(entity);
ObjectMapper objectMapper = new ObjectMapper();
Rule targetRule = objectMapper.readValue(json, Rule.class);
boolean correctStatus = HTTPcode >= 200 && HTTPcode <= 300 ? true : false;
boolean correctResponse = targetRule != null ? true : false;
assertTrue(correctStatus);
assertTrue(correctResponse);
}
I get nullpointer exception on my ruleService. It is the same even if I try to #Autowire it and not instantiate it. I guess the whole approach about getting one rule object from the mongo database is wrong, but putting an object locally in my database and getting this object by his id would be even worse, since these tests will not run on my computer.
This is the exception if I try to autowire my service
java.lang.NullPointerException
at com.%%%%.^^^^.controller.v2.test.RuleControllerTest.loadOneRule(RuleControllerTest.java:96)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at org.junit.runner.JUnitCore.run(JUnitCore.java:115)
at org.junit.vintage.engine.execution.RunnerExecutor.execute(RunnerExecutor.java:42)
at java.util.stream.ForEachOps$ForEachOp$OfRef.accept(Unknown Source)
at java.util.stream.ReferencePipeline$3$1.accept(Unknown Source)
at java.util.Iterator.forEachRemaining(Unknown Source)
at java.util.Spliterators$IteratorSpliterator.forEachRemaining(Unknown Source)
at java.util.stream.AbstractPipeline.copyInto(Unknown Source)
at java.util.stream.AbstractPipeline.wrapAndCopyInto(Unknown Source)
at java.util.stream.ForEachOps$ForEachOp.evaluateSequential(Unknown Source)
at java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(Unknown Source)
at java.util.stream.AbstractPipeline.evaluate(Unknown Source)
at java.util.stream.ReferencePipeline.forEach(Unknown Source)
at org.junit.vintage.engine.VintageTestEngine.executeAllChildren(VintageTestEngine.java:83)
at org.junit.vintage.engine.VintageTestEngine.execute(VintageTestEngine.java:74)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:170)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:154)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:90)
at org.eclipse.jdt.internal.junit5.runner.JUnit5TestReference.run(JUnit5TestReference.java:86)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:538)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:760)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:460)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:206)
You don't need make request using HttpClient, rather you can use #WebMVCTest to test your controller. One more thing, you don't need to specify the dependencies by creating objects rather mock them using #MockBean. In code below you specify the exact controller name within #WebMvcTest annotation.
#RunWith(SpringRunner.class)
#WebMvcTest(value = YourController.class, secure = false)
public class YourControllerTest {
#Autowired
private MockMvc mockMvc;
#MockBean
private StudentService rulesService;
Rule mockRule = new Rule();
#Test
public void testLoadOneRule() throws Exception {
Mockito.when(
rulesService.loadOneRule(Mockito.anyString(),
Mockito.anyString())).thenReturn(mockCourse);
RequestBuilder requestBuilder = MockMvcRequestBuilders.get(
"/{ruleId}","rule1")
MvcResult result = mockMvc.perform(requestBuilder).andReturn();
System.out.println(result.getResponse());
String expected = "{id:rule1,name:'RuleName'}";
JSONAssert.assertEquals(expected, result.getResponse()
.getContentAsString(), false);
}
}

NullPointerExecption failure when creating unit test for java spring controller

I'm very new to Mockito and JUnit. I'm working on creating a test case for "forgot password"-workflow. Below is the code for the controller and the test. The test case fails because of a NullPointerException. I added the stacktrace below. Could anyone help me to fix the code? Thanks!
#RequestMapping(value = "/user/public/forgotPassword", method = RequestMethod.POST)
public ModelAndView sendforgetPasswordLink(#ModelAttribute ForgetPasswordBean forgetPasswordBean,BindingResult result, HttpSession session) {
BreadCrumbBuilder.addLinktoBreadCrumb(session, new Link(Constants.FORGET_PASSWORD_TITLE, "/user/public/forgotPassword", Constants.GROUP_USER, 0));
Map<String, String> breadCrumbs = HomePageController.setupInitialBreadCrumbs(session);
breadCrumbs.put(Constants.FORGET_PASSWORD_TITLE, "/user/public/forgotPassword");
session.setAttribute(SessionAttributes.BREAD_CRUMBS,breadCrumbs);
ModelAndView mav = new ModelAndView();
mav.addObject("displayTitle", Constants.FORGET_PASSWORD_TITLE);
PublicUser user = publicUserService.findPublicUserByEmail(forgetPasswordBean.getEmail().toLowerCase());
if(user == null) {
result.reject("email", "An account does not exist for this email.");
mav.setViewName("publicuser/forgetPassword.jsp");
return mav;
}
String randomId = java.util.UUID.randomUUID().toString();
user.setTempId(randomId);
mailService.sendForgetPasswordLink(user);
publicUserService.savePublicUser(user);
String msg = "Password reset instructions have been sent to your email.";
mav.addObject("msg", msg);
mav.setViewName("message.jsp");
return mav;
}
This is test I created so far
#Test
public void TestForgetPasswordForNoUserFound() throws Exception {
final String input_email = "abc#test.com";
ForgetPasswordBean forgetPasswordBean = new ForgetPasswordBean();
forgetPasswordBean.setEmail(input_email);
when(mockPublicUserService.findPublicUserByEmail(input_email)).thenReturn(null);
final ModelAndView modelAndView = controller.sendforgetPasswordLink(forgetPasswordBean, mockBindingResult, mockHttpSession);
verify(mockBindingResult).reject("email", "An account does not exist for this email.");
assertEquals("publicuser/forgetPassword.jsp", modelAndView.getViewName());
assertModelAttributeValue(modelAndView, "displayTitle", Constants.FORGET_PASSWORD_TITLE);
}
The trace starts here
java.lang.NullPointerException
at gov.hhs.cdelr.web.PublicUserControllerTest.TestForgetPasswordForNoUserFound(PublicUserControllerTest.java:105)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
Line 410 is this line:
result.reject("email", "An account does not exist for this email.");
As the code of your test does not seem to be complete, i assume you forgot to initialize mockBindingResult for this testcase.
Sadly i can't tell you more as i do not see a setUp method nor the rest of the test class.
A setup method could be helpful, as it will run before every test, in there you should initialize your mockBindingResult.
#Before
public void setUp() {
// Do Stuff before every test
}

JUnit for RestController with parameter PersistentEntityResourceAssembler

could you please help me.
I try to implement an JUnit-Test for a Restcontroller with parameter PersistentEntityResourceAssembler.
Here is my RestController:
import java.util.Map;
import org.apache.camel.ProducerTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.rest.webmvc.PersistentEntityResourceAssembler;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
#RestController
public class GreetingController2 {
#Autowired
ProducerTemplate pt;
#RequestMapping(value = "/greeting2", method = RequestMethod.POST)
public ResponseEntity<Greeting> updateGreeting( PersistentEntityResourceAssembler assembler,
#RequestHeader HttpHeaders header, #RequestBody Greeting greeting) {
Map<String, Object> headers = (Map) header.toSingleValueMap();
greeting=(Greeting) pt.requestBodyAndHeaders("direct:start", greeting, headers);
return new ResponseEntity<Greeting>(greeting, HttpStatus.OK);
}
}
And my JunitTest:
public class GreetingControllerMocksTest2 extends AbstractControllerTest2 {
#Mock
private ProducerTemplate producerTemplate;
#InjectMocks
private GreetingController2 greetingController2;
#Before
public void setUp() {
// Initialize Mockito annotated components
MockitoAnnotations.initMocks(this);
// Prepare the Spring MVC Mock components for standalone testing
setUp(greetingController2);
}
#Test
public void testRestEndpoint() throws Exception {
// Create some test data
Greeting entity = new Greeting(5,"Rudi");
// Stub the GreetingService.update method return value
when(producerTemplate.requestBodyAndHeaders(anyString(),anyObject(),
anyObject())).thenReturn(entity);
// Perform the behavior being tested
String uri = "/greeting2";
String inputJson = super.mapToJson(entity);
MvcResult result = mvc
.perform(MockMvcRequestBuilders.post(uri)
.contentType(MediaType.APPLICATION_JSON)
.accept(MediaType.APPLICATION_JSON).content(inputJson))
.andReturn();
// Extract the response status and body
String content = result.getResponse().getContentAsString();
int status = result.getResponse().getStatus();
// Verify the GreetingService.update method was invoked once
verify(producerTemplate,
times(1)).requestBodyAndHeaders(anyString(),anyObject(),anyObject());
// Perform standard JUnit assertions on the test results
Assert.assertEquals("failure - expected HTTP status 200", 200, status);
Assert.assertTrue(
"failure - expected HTTP response body to have a value",
content.trim().length() > 0);
Greeting updatedEntity = super.mapFromJson(content, Greeting.class);
Assert.assertNotNull("failure - expected entity not null",
updatedEntity);
}
}
When starting the junit-test i get the following Exception:
org.springframework.web.util.NestedServletException: Request processing failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.data.rest.webmvc.PersistentEntityResourceAssembler]: No default constructor found; nested exception is java.lang.NoSuchMethodException: org.springframework.data.rest.webmvc.PersistentEntityResourceAssembler.<init>()
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:979)
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:869)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:648)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:843)
at org.springframework.test.web.servlet.TestDispatcherServlet.service(TestDispatcherServlet.java:65)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
at org.springframework.mock.web.MockFilterChain$ServletFilterProxy.doFilter(MockFilterChain.java:167)
at org.springframework.mock.web.MockFilterChain.doFilter(MockFilterChain.java:134)
at org.springframework.test.web.servlet.MockMvc.perform(MockMvc.java:155)
at org.example.ws.web.api.GreetingControllerMocksTest2.testRestEndpoint(GreetingControllerMocksTest2.java:83)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75)
at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86)
at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:254)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:89)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:193)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.data.rest.webmvc.PersistentEntityResourceAssembler]: No default constructor found; nested exception is java.lang.NoSuchMethodException: org.springframework.data.rest.webmvc.PersistentEntityResourceAssembler.<init>()
at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:107)
at org.springframework.web.method.annotation.ModelAttributeMethodProcessor.createAttribute(ModelAttributeMethodProcessor.java:137)
at org.springframework.web.servlet.mvc.method.annotation.ServletModelAttributeMethodProcessor.createAttribute(ServletModelAttributeMethodProcessor.java:80)
at org.springframework.web.method.annotation.ModelAttributeMethodProcessor.resolveArgument(ModelAttributeMethodProcessor.java:106)
at org.springframework.web.method.support.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:99)
at org.springframework.web.method.support.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:161)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:128)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:110)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:832)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:743)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:961)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:895)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:967)
... 39 more
Caused by: java.lang.NoSuchMethodException: org.springframework.data.rest.webmvc.PersistentEntityResourceAssembler.<init>()
at java.lang.Class.getConstructor0(Unknown Source)
at java.lang.Class.getDeclaredConstructor(Unknown Source)
at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:104)
... 52 more
If i remove the paramter PersistentEntityResourceAssembler, then everthing works fine. But der RestController is generated by a tool, so it is not possible for me to remove this.
From your controller method I don't see if you are using PersistentEntityResourceAssembler. Please check your use case. To fix this, in your controller, you can use #RepositoryRestController instead of #RestController. Please check http://docs.spring.io/spring-data/rest/docs/current/reference/html/#customizing-sdr.overriding-sdr-response-handlers. I found the similar issue has been reported for some different use case. This issue is still in open state. https://jira.spring.io/browse/DATAREST-657
It seems that you have missed something.
I faced this error and fixed it, the problem was that I forgot to add an annotation #RequestBody to the parameter of the method.
Next code works fine:
//interface:
#ResponseStatus(value = HttpStatus.ACCEPTED)
#RequestMapping(method = RequestMethod.POST, produces = { MediaType.APPLICATION_JSON_VALUE }, consumes = { MediaType.APPLICATION_JSON_VALUE })
public Message greeting(#RequestBody GreetingRequestMessage requestMessage);
//implementation:
public Message greeting(#RequestBody GreetingRequestMessage requestMessage) {
}
//setup #Before:
mvc = MockMvcBuilders.standaloneSetup(testObj).build();
GreetingRequestMessage requestMessage = new GreetingRequestMessage();
payloadString = mapper.writeValueAsString(requestMessage);
//test:
payloadString = mapper.writeValueAsString(request);
mvc.perform(
MockMvcRequestBuilders.post("/greeting")
.content(payloadString)
.contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON))
.andExpect(status().is(202));

java.lang.AssertionError: expected:<200> but was:<404> in jersey restful services unit test

I have this class JerseySpringSuiteTest.java:
#RunWith(Suite.class)
#Suite.SuiteClasses({ ProductTest.class })
public class JerseySpringSuiteTest {
public static JerseyTest jerseyTest;
#BeforeClass
public static void init() {
jerseyTest = new JerseyTest(new WebAppDescriptor.Builder("com.product.resource")
.contextParam("contextConfigLocation", "classpath:applicationContext.xml").servletClass(SpringServlet.class)
.contextListenerClass(ContextLoaderListener.class).requestListenerClass(RequestContextListener.class).build()) {
};
}
}
and ProductTest.java:
public class ProductTest{
#Before
public void before() throws Exception {
JerseySpringSuiteTest.jerseyTest.setUp();
ExecutorService productExecutorService = ContextLoaderListener.getCurrentWebApplicationContext().getBean(
"productExecutorService", ExecutorService.class);
Assert.assertNotNull(productExecutorService);
}
#Test
public void testNoAction() {
WebResource webResource = JerseySpringSuiteTest.jerseyTest.resource();
String responseMsg = webResource.path("product/").get(String.class);
Assert.assertEquals("No Action Specified", responseMsg);
}
#Test
public void testGetProducts() throws URISyntaxException {
WebResource webResource = JerseySpringSuiteTest.jerseyTest.resource().path(
"Products/rest/product/getProducts/1/productName/01-01-2013/");
ClientResponse response = webResource.accept(MediaType.APPLICATION_JSON).get(ClientResponse.class);
Assert.assertEquals(200, response.getStatus());
}
}
and Product.java:
#Component
#Path("/product")
public class Product{
#Autowired
private ProductService productService;
#GET
#Produces(MediaType.APPLICATION_JSON)
public Object noAction() {
return "No Action Specified";
}
#GET
#Path("/getProducts/{companyID}/{companyName}/{date}")
#Produces(MediaType.APPLICATION_JSON)
public Object getProducts(#PathParam("companyID") final int companyID,
#PathParam("date") final String date, #PathParam("companyName") final String companyName)
throws IOException {
return productService.getProducts(companyID, companyName, date);
}
}
When I execute it I see:
java.lang.AssertionError: expected:<200> but was:<404>
at org.junit.Assert.fail(Assert.java:88)
at org.junit.Assert.failNotEquals(Assert.java:743)
at org.junit.Assert.assertEquals(Assert.java:118)
at org.junit.Assert.assertEquals(Assert.java:555)
at org.junit.Assert.assertEquals(Assert.java:542)
at com.product.resource.MonitoringEngineResourceTest.testGetProducts(ProductTest.java:27)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
at org.junit.runners.Suite.runChild(Suite.java:127)
at org.junit.runners.Suite.runChild(Suite.java:26)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
I am able to get data when I ping URL in browser.
Could some one please help me to get response status as 200 and JSON object?
NOTE: I am using jersey 1.17.1 version and grizzly2 container.
According to your noAction unit test, the correct URL seems to be:
webResource.path("product/")
This is also confirmed by your actual service class:
#Path("/product")
public class Product {
//...
}
This means that you need to change your other test to use the same path.
Also, it is companyName, not productName as per your service class.
#Test
public void testGetProducts() throws URISyntaxException {
WebResource webResource = JerseySpringSuiteTest.jerseyTest.resource();
ClientResponse response =
webResource.path("product/getProducts/1/companyName/01-01-2013/")
.accept(MediaType.APPLICATION_JSON)
.get(ClientResponse.class);
Assert.assertEquals(200, response.getStatus());
}
One possible reason that it works in a browser is that your server (Tomcat, Jetty, etc.) is configured to add the common URL prefix Products/rest to all paths. This server is not in the picture when you execute unit tests.

Categories