I am learning unit testing of spring controller with EasyMock and Spring test framework. I have done a simple unit testing for my controller.
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;
import com.firstmav.domain.Employee;
import com.firstmav.service.EmployeeService;
#Controller
public class DataController {
#Autowired
EmployeeService employeeservice;
#RequestMapping("form")
public ModelAndView getform(#ModelAttribute Employee employee){
return new ModelAndView("form");
}
#RequestMapping("reguser")
public ModelAndView registeruser(#ModelAttribute Employee employee){
employeeservice.insertRow(employee);
return new ModelAndView("redirect:list");
}
#RequestMapping("list")
public ModelAndView getlist(){
List<Employee> employeelist = employeeservice.getList();
return new ModelAndView("list", "employeeList", employeelist);
}
#RequestMapping("delete")
public ModelAndView deleteitem(#RequestParam int id){
employeeservice.deleteRow(id);
return new ModelAndView("redirect:list");
}
#RequestMapping("edit")
public ModelAndView edititem(#ModelAttribute Employee employee, #RequestParam int id){
Employee employeeObject = employeeservice.getRowByID(id);
return new ModelAndView("edit", "employeeObject", employeeObject);
}
#RequestMapping("update")
public ModelAndView updaterow(#ModelAttribute Employee employee){
employeeservice.updateRow(employee);
return new ModelAndView("redirect:list");
}
}
and i have my failing test case here.
import org.junit.Before;
import org.junit.Test;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
import com.firstmav.controller.DataController;
public class DataControllerTest {
private MockMvc mockmvc;
#Before
public void setup(){
InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
viewResolver.setPrefix("/WEB-INF/pages/");
viewResolver.setSuffix(".jsp");
mockmvc = MockMvcBuilders.standaloneSetup(new DataController()).setViewResolvers(viewResolver).build();
}
#Test
public void main() throws Exception{
mockmvc.perform(get("/form")).andExpect(status().isOk()).andExpect(view().name("form"));
}
}
I have included the controller import in the test case but i always getting the noclassdeffound exception.
java.lang.NoClassDefFoundError: javax/servlet/ServletException
at org.springframework.test.web.servlet.setup.MockMvcBuilders.standaloneSetup(MockMvcBuilders.java:71)
at com.ada.test.DataControllerTest.setup(DataControllerTest.java:23)
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.RunBefores.evaluate(RunBefores.java:24)
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: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)
Caused by: java.lang.ClassNotFoundException: javax.servlet.ServletException
at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
at java.lang.ClassLoader.loadClass(ClassLoader.java:425)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
at java.lang.ClassLoader.loadClass(ClassLoader.java:358)
... 25 more
I don't understand where i am making the mistake. Can any one help me or point me to right direction?
The issue is not related with your code.You're missing the library(jar) which contains javax.servlet.ServletException.So at runtime you're getting this exception.Check you class path if you have the servlet-api.jar in that location.
Though adding servlet-api.jar into your class path location should resolve the issue but if you want you can also check the jars that have this class here
Related
I'm developing a Spring boot web application. and I'm working on spring boot to test the rest api to get hospital list, but i'am getting the following exception every time
org.springframework.web.util.NestedServletException: Request processing failed; nested exception is java.lang.NullPointerException
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1013)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:897)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:634)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:882)
at org.springframework.test.web.servlet.TestDispatcherServlet.service(TestDispatcherServlet.java:66)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:741)
at org.springframework.mock.web.MockFilterChain$ServletFilterProxy.doFilter(MockFilterChain.java:166)
at org.springframework.mock.web.MockFilterChain.doFilter(MockFilterChain.java:133)
at org.springframework.test.web.servlet.MockMvc.perform(MockMvc.java:166)
at com.bezkoder.springjwt.Controller.HospitalControllerTest.testgetAllHospitals(HospitalControllerTest.java:134)
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.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
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.mockito.internal.runners.DefaultInternalRunner$1.run(DefaultInternalRunner.java:78)
at org.mockito.internal.runners.DefaultInternalRunner.run(DefaultInternalRunner.java:84)
at org.mockito.internal.runners.StrictRunner.run(StrictRunner.java:39)
at org.mockito.junit.MockitoJUnitRunner.run(MockitoJUnitRunner.java:161)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:69)
at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:33)
at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:221)
at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:54)
Caused by: java.lang.NullPointerException
at com.bezkoder.springjwt.controllers.HospitalController.getAllHospitals(HospitalController.java:64)
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:190)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:138)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:104)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:892)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:797)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1039)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:942)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1005)
... 36 more
this is my test
package com.bezkoder.springjwt.Controller;
import com.bezkoder.springjwt.controllers.HospitalController;
import com.bezkoder.springjwt.models.Hospital;
import com.bezkoder.springjwt.repository.HospitalRepository;
import com.bezkoder.springjwt.services.HospitalService;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
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.mockito.junit.MockitoJUnitRunner;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.mock.web.MockHttpServletResponse;
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 org.springframework.test.web.servlet.setup.MockMvcBuilders;
import java.util.ArrayList;
import java.util.List;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.core.IsEqual.equalTo;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat;
#RunWith(MockitoJUnitRunner.class)
public class HospitalControllerTest {
#Mock
private HospitalService hospitalService;
#Mock
private HospitalRepository hospitalRepository;
#InjectMocks
private HospitalController hospitalController;
#Before
public void setUp() throws Exception {
mockMvc = MockMvcBuilders.standaloneSetup(hospitalController).build();
}
private MockMvc mockMvc;
private String mapToJson(Object object) throws JsonProcessingException {
ObjectMapper objectMapper = new ObjectMapper();
return objectMapper.writeValueAsString(object);
}
#Test
public void testcreateHospital() throws Exception {
Hospital hospital = new Hospital();
hospital.setId((long) 1);
hospital.setName("appellib");
hospital.setAdministrativeAddress("ad1234");
hospital.setFinessNumber(123456);
hospital.setSiretNumber(123456);
String uri = "/api/auth/hospital/add";
// String inputInJson = this.mapToJson(hospital);
String inputInJson = this.mapToJson(hospital);
// MvcResult result = mockMvc.perform(requestBuilder).andReturn();
MvcResult mvcResult = mockMvc.perform(MockMvcRequestBuilders.post(uri)
.contentType(MediaType.APPLICATION_JSON_VALUE)
.content(inputInJson)).andReturn();
int status = mvcResult.getResponse().getStatus();
assertEquals(200, status);
String content = mvcResult.getResponse().getContentAsString();
assertEquals(content, "Hospital is created successfully");
}
#Test
public void testgetAllHospitals() throws Exception{
String uri = "/api/auth/hospital/display";
Hospital hospital = new Hospital();
hospital.setId((long) 1);
hospital.setName("appellib");
hospital.setAdministrativeAddress("ad1234");
hospital.setFinessNumber(123456);
hospital.setSiretNumber(123456);
Hospital hospital1 = new Hospital();
hospital1.setId((long) 2);
hospital1.setName("Aled");
hospital1.setAdministrativeAddress("ad4567");
hospital1.setFinessNumber(98765);
hospital1.setSiretNumber(1256767);
List<Hospital> hospitalsList = new ArrayList<>();
hospitalsList.add(hospital);
hospitalsList.add(hospital1);
Mockito.when(hospitalService.findAll()).thenReturn(hospitalsList);
RequestBuilder requestBuilder = MockMvcRequestBuilders.get(uri).accept(MediaType.APPLICATION_JSON);
MvcResult result = mockMvc.perform(requestBuilder).andReturn();
String expectedJson = this.mapToJson(hospitalsList);
String outputInJson = result.getResponse().getContentAsString();
MockHttpServletResponse response = result.getResponse();
assertThat(outputInJson, is(equalTo(expectedJson)));
assertEquals(HttpStatus.OK.value(), response.getStatus());
}
}
and this is the function i'm testing
package com.bezkoder.springjwt.controllers;
import com.bezkoder.springjwt.models.Hospital;
import com.bezkoder.springjwt.payload.response.MessageResponse;
import com.bezkoder.springjwt.repository.HospitalRepository;
import com.bezkoder.springjwt.services.HospitalServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import java.util.List;
import java.util.logging.Logger;
#Controller
#RequestMapping("/api/auth/hospital")
public class HospitalController {
Logger logger = Logger.getLogger("com.Appel.lib.Controller.HospitalController");
#Autowired
HospitalServiceImpl hospitalService;
#Autowired
HospitalRepository hospitalRepository;
#PostMapping("/add")
public ResponseEntity<?> createHospital(#RequestBody Hospital hospital){
if (hospitalService.existsByName(hospital.getName())) {
return ResponseEntity
.badRequest()
.body(new MessageResponse("Error: name is already taken!"));
}
if (hospitalService.existsByAdministrativeAddress(hospital.getAdministrativeAddress())) {
return ResponseEntity
.badRequest()
.body(new MessageResponse("Error: administrative_address is already in use!"));
}
if (hospitalService.existsByFinessNumber(hospital.getFinessNumber())) {
return ResponseEntity
.badRequest()
.body(new MessageResponse("Error: finess_number is already taken!"));
}
if (hospitalService.existsBySiretNumber(hospital.getSiretNumber())) {
return ResponseEntity
.badRequest()
.body(new MessageResponse("Error: siret_number is already in use!"));
}
hospitalService.add(hospital);
return ResponseEntity.ok(new MessageResponse("Hospital registered successfully!"));
}
#GetMapping("/display")
public ResponseEntity<List<Hospital>> getAllHospitals() {
logger.info("Getting all Hospitals from hospital table...Call getAllHospitals ");
List<Hospital> hospitals = hospitalService.findAll();
logger.info("Data extracted from hospital table...");
return ResponseEntity.ok(hospitals) ;
}
}
i searched stackoverflow for any solution to a similar error, but i didn't find any, any solution suggested to fix this ?
Instead of :
return ResponseEntity.ok(hospitals) ;
Try this :
return ResponseEntity<List<hospitals>>(hospitals);
at com.bezkoder.springjwt.controllers.HospitalController.getAllHospitals(HospitalController.java:64)
check the object at line 64 it return null
I am trying to apply junit test for my rest controllers.
I've tried to apply junit 4 but I got 404 error instead 200.
It looks like something is not initialized but cant't figured what.
Here is tutorial I have tried to apply.
https://www.youtube.com/watch?v=8S8o46avgAw
I also tried some different tutorials with junit 5 but the result was the same.
Here you can find the whole project.
https://github.com/WojciechWeg/tiny-bank/tree/tests
Just before publishing this post I've applied the following:
#Before
public void setUp() throws Exception {
mockMvc = MockMvcBuilders.standaloneSetup(customerController)
.build();
customer = new Customer("Jan","Kowalski",new Date(),"Marszalkowska",new ArrayList<>());
customerService.createNewCustomer(customer);
System.out.println("Customers from service: "+ customerService.getAllCustomers());
}
But the result of it is:
Customers from service: []
So it returns nothing. Above snippet is not in repo link.
Rest controller class:
package com.tinybank.tinybankapi.controllers;
import com.tinybank.tinybankapi.model.Account;
import com.tinybank.tinybankapi.model.Customer;
import com.tinybank.tinybankapi.model.CustomerResource;
import com.tinybank.tinybankapi.services.CustomerService;
import org.springframework.hateoas.Link;
import org.springframework.hateoas.Resources;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.mvc.method.annotation.MvcUriComponentsBuilder;
import org.springframework.web.servlet.support.ServletUriComponentsBuilder;
import javax.validation.Valid;
import java.net.URI;
import java.util.List;
#RestController
#RequestMapping(CustomerController.BASE_URL)
public class CustomerController {
public static final String BASE_URL = "api/customers";
private final CustomerService customerService;
public CustomerController(CustomerService customerService) {
this.customerService = customerService;
}
#GetMapping
#ResponseStatus(HttpStatus.OK)
public ResponseEntity<Resources<List<Customer>>> getListOfCustomers() {
Resources<List<Customer>> resources = new Resources(customerService.getAllCustomers());
String uri = ServletUriComponentsBuilder.fromCurrentRequest().build().toUriString();
resources.add(new Link(uri,"self"));
return ResponseEntity.ok(resources);
}
#GetMapping({"/{id}"})
#ResponseStatus(HttpStatus.OK)
public Customer getCustomer(#PathVariable Long id) {
return customerService.getCustomerById(id);
}
#DeleteMapping({"/{id}"})
#ResponseStatus(HttpStatus.OK)
public void deleteCustomer(#PathVariable Long id) {
customerService.deleteCustomerById(id);
}
#PostMapping
#ResponseStatus(HttpStatus.CREATED)
public ResponseEntity<CustomerResource> createNewCustomer(#RequestBody #Valid Customer Customer) {
Customer customer = customerService.createNewCustomer(Customer);
URI uri = MvcUriComponentsBuilder.fromController(getClass())
.path("/{id}")
.buildAndExpand(customer.getId())
.toUri();
return ResponseEntity.created(uri).body(new CustomerResource(customer));
}
#PutMapping({"/{id}/open_account"})
#ResponseStatus(HttpStatus.OK)
public void openAccount(#PathVariable Long id, #RequestBody Account account) {
customerService.openAccount(id, account);
}
}
Test class:
package com.tinybank.tinybankapi.controllers;
import com.tinybank.tinybankapi.model.Customer;
import com.tinybank.tinybankapi.services.CustomerService;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import java.util.ArrayList;
import java.util.Date;
import static org.junit.Assert.*;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.when;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
#RunWith(SpringJUnit4ClassRunner.class)
public class CustomerControllerTest {
private MockMvc mockMvc;
#Mock
private CustomerService customerService;
#InjectMocks
private CustomerController customerController;
Customer customer;
#Before
public void setUp() throws Exception {
mockMvc = MockMvcBuilders.standaloneSetup(customerController)
.build();
customer = new Customer("Jan","Kowalski",new Date(),"Marszalkowska",new ArrayList<>());
customerService.createNewCustomer(customer);
System.out.println("Customers from service: "+ customerService.getAllCustomers());
}
#Test
public void getCustomer() throws Exception {
when(customerService.getCustomerById(any())).thenReturn(customer);
mockMvc.perform(get("api/customers/1"))
.andExpect(status().isOk());
}
}
This is how stack trace looks like:
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:195)
at com.tinybank.tinybankapi.controllers.CustomerControllerTest.getCustomer(CustomerControllerTest.java:53)
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:74)
at org.springframework.test.context.junit4.statements.RunAfterTestExecutionCallbacks.evaluate(RunAfterTestExecutionCallbacks.java:84)
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)
Have you tried below approach without injecting mocks?
MockMvcBuilders.standaloneSetup(new CustomerController())
.build();
EDIT:
I've ran your code locally.
Do this:
mockMvc = MockMvcBuilders.standaloneSetup(new CustomerController(customerService))
.build();
And add slash to the beginning of URL
mockMvc.perform(get("/api/customers/1"))
.andExpect(status().isOk());
I tried:
#BeforeClass
public static void setUpClass() {
CurieProvider curieProvider = new DefaultCurieProvider("a", new UriTemplate("a{yey}"));
RelProvider relProvider = new DefaultRelProvider();
ObjectMapper halObjectMapper = JsonUtils.mapper;
halObjectMapper.registerModule(new Jackson2HalModule());
halObjectMapper.setHandlerInstantiator(new Jackson2HalModule.HalHandlerInstantiator(relProvider, curieProvider));
}
but still got error:
03:26:25.936 [main] ERROR org.soluvas.json.JsonUtils - Cannot serialize id.co.bippo.product.rs.commerceplug.ProductOrServiceImpl as JSON
com.fasterxml.jackson.databind.JsonMappingException: Class org.springframework.hateoas.hal.Jackson2HalModule$HalLinkListSerializer has no default (no arg) constructor
at com.fasterxml.jackson.databind.SerializerProvider._createAndCacheUntypedSerializer(SerializerProvider.java:1042) ~[jackson-databind-2.4.3.jar:2.4.3]
at com.fasterxml.jackson.databind.SerializerProvider.findValueSerializer(SerializerProvider.java:445) ~[jackson-databind-2.4.3.jar:2.4.3]
at com.fasterxml.jackson.databind.SerializerProvider.findTypedValueSerializer(SerializerProvider.java:599) ~[jackson-databind-2.4.3.jar:2.4.3]
at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider.serializeValue(DefaultSerializerProvider.java:92) ~[jackson-databind-2.4.3.jar:2.4.3]
at com.fasterxml.jackson.databind.ObjectWriter._configAndWriteValue(ObjectWriter.java:800) ~[jackson-databind-2.4.3.jar:2.4.3]
at com.fasterxml.jackson.databind.ObjectWriter.writeValueAsString(ObjectWriter.java:676) ~[jackson-databind-2.4.3.jar:2.4.3]
at org.soluvas.json.JsonUtils.asJson(JsonUtils.java:54) ~[classes/:na]
at id.co.bippo.product.rs.commerceplug.ProductOrServiceImplTest.productOrService(ProductOrServiceImplTest.java:41) [test-classes/:na]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_20]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_20]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_20]
at java.lang.reflect.Method.invoke(Method.java:483) ~[na:1.8.0_20]
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47) [junit-4.11.jar:na]
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) [junit-4.11.jar:na]
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44) [junit-4.11.jar:na]
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17) [junit-4.11.jar:na]
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271) [junit-4.11.jar:na]
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70) [junit-4.11.jar:na]
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50) [junit-4.11.jar:na]
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238) [junit-4.11.jar:na]
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63) [junit-4.11.jar:na]
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236) [junit-4.11.jar:na]
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53) [junit-4.11.jar:na]
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229) [junit-4.11.jar:na]
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26) [junit-4.11.jar:na]
at org.junit.runners.ParentRunner.run(ParentRunner.java:309) [junit-4.11.jar:na]
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50) [.cp/:na]
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) [.cp/:na]
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459) [.cp/:na]
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675) [.cp/:na]
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382) [.cp/:na]
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192) [.cp/:na]
Caused by: java.lang.IllegalArgumentException: Class org.springframework.hateoas.hal.Jackson2HalModule$HalLinkListSerializer has no default (no arg) constructor
at com.fasterxml.jackson.databind.util.ClassUtil.createInstance(ClassUtil.java:370) ~[jackson-databind-2.4.3.jar:2.4.3]
at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider.serializerInstance(DefaultSerializerProvider.java:474) ~[jackson-databind-2.4.3.jar:2.4.3]
at com.fasterxml.jackson.databind.ser.BasicSerializerFactory.findSerializerFromAnnotation(BasicSerializerFactory.java:461) ~[jackson-databind-2.4.3.jar:2.4.3]
at com.fasterxml.jackson.databind.ser.BeanSerializerFactory._constructWriter(BeanSerializerFactory.java:708) ~[jackson-databind-2.4.3.jar:2.4.3]
at com.fasterxml.jackson.databind.ser.BeanSerializerFactory.findBeanProperties(BeanSerializerFactory.java:557) ~[jackson-databind-2.4.3.jar:2.4.3]
at com.fasterxml.jackson.databind.ser.BeanSerializerFactory.constructBeanSerializer(BeanSerializerFactory.java:344) ~[jackson-databind-2.4.3.jar:2.4.3]
at com.fasterxml.jackson.databind.ser.BeanSerializerFactory.findBeanSerializer(BeanSerializerFactory.java:263) ~[jackson-databind-2.4.3.jar:2.4.3]
at com.fasterxml.jackson.databind.ser.BeanSerializerFactory._createSerializer2(BeanSerializerFactory.java:222) ~[jackson-databind-2.4.3.jar:2.4.3]
at com.fasterxml.jackson.databind.ser.BeanSerializerFactory.createSerializer(BeanSerializerFactory.java:152) ~[jackson-databind-2.4.3.jar:2.4.3]
at com.fasterxml.jackson.databind.SerializerProvider._createUntypedSerializer(SerializerProvider.java:1077) ~[jackson-databind-2.4.3.jar:2.4.3]
at com.fasterxml.jackson.databind.SerializerProvider._createAndCacheUntypedSerializer(SerializerProvider.java:1037) ~[jackson-databind-2.4.3.jar:2.4.3]
... 31 common frames omitted
I'm guessing you're doing more "integration" testing than unit testing if you need the converters setup as controllers don't return converted responses. I may suggest adding annotations like this to your test class
#RunWith(SpringJUnit4ClassRunner.class)
#WebAppConfiguration
#SpringApplicationConfiguration(classes = Application.class)
which will allow you to have this injection:
#Autowired
protected WebApplicationContext wac;
Which you can then pass to the MockMVC builder in your setup:
MockMvcBuilders.webAppContextSetup(wac).build()
Application.class would be something annotated with #ComponentScan that in turn gets all your configurations. You can pass them in explicitly too.
If you really want to generate the converter explicitly here's what we have:
public static HttpMessageConverter<Object> HALMessageConverter(){
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.registerModule(new Jackson2HalModule());
//TODO: need to figure out this curie provider stuff...more in production mode
DefaultCurieProvider curieProvider = new DefaultCurieProvider("a", new UriTemplate("http://localhost:8080/myapp/rels/{rel}"));
DefaultRelProvider relProvider = new DefaultRelProvider();
objectMapper.setHandlerInstantiator(new Jackson2HalModule.HalHandlerInstantiator(relProvider, curieProvider));
MappingJackson2HttpMessageConverter halConverter = new MappingJackson2HttpMessageConverter();
halConverter.setObjectMapper(objectMapper);
halConverter.setSupportedMediaTypes(Arrays.asList(MediaTypes.HAL_JSON));
return halConverter;
}
and then you must register this converter with an MVC instance:
var mockMVC = MockMvcBuilders.standaloneSetup(controller)
.setMessageConverters(HALMessageConverter())
.build();
Looks like the media type and registering are what you may be missing.
Final note, that exception is something very different altogether. I've seen that when you instantiate an ObjectMapper that uses the existing mixin's but a different list serializer. This is because the resource mixin defines the HalListLinkSerializer as a serializer, but relies on proper instantiation. Not sure why you're getting that...guessing you have some annotation config going on somewhere...
This is what worked for me:
import java.io.IOException;
import org.junit.BeforeClass;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.soluvas.json.JsonUtils;
import org.soluvas.json.LowerEnumSerializer;
import org.springframework.hateoas.MediaTypes;
import org.springframework.hateoas.RelProvider;
import org.springframework.hateoas.UriTemplate;
import org.springframework.hateoas.core.DefaultRelProvider;
import org.springframework.hateoas.hal.CurieProvider;
import org.springframework.hateoas.hal.DefaultCurieProvider;
import org.springframework.hateoas.hal.Jackson2HalModule;
import org.springframework.http.converter.HttpMessageNotWritableException;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.mock.http.MockHttpOutputMessage;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.collect.ImmutableList;
public class ProductHalJsonTest {
private static final Logger log = LoggerFactory
.getLogger(ProductHalJsonTest.class);
private static MappingJackson2HttpMessageConverter halConverter;
#BeforeClass
public static void setUpClass() {
CurieProvider curieProvider = new DefaultCurieProvider("a", new UriTemplate("a{yey}"));
RelProvider relProvider = new DefaultRelProvider();
ObjectMapper halObjectMapper = JsonUtils.mapper;
LowerEnumSerializer.LOWER = false;
halObjectMapper.registerModule(new Jackson2HalModule());
halObjectMapper.setHandlerInstantiator(new Jackson2HalModule.HalHandlerInstantiator(relProvider, curieProvider));
halConverter = new MappingJackson2HttpMessageConverter();
halConverter.setObjectMapper(halObjectMapper);
halConverter.setSupportedMediaTypes(ImmutableList.of(MediaTypes.HAL_JSON));
}
#Test
public void product() throws HttpMessageNotWritableException, IOException {
Brand brand = new Brand().withName("Tuneeca");
Product product = new Product()
.withName("T-2081239")
.withBrand(brand)
.addOffer(new Offer().withAvailability(ItemAvailability.IN_STOCK));
// String json = JsonUtils.asJson(product);
final MockHttpOutputMessage msg = new MockHttpOutputMessage();
halConverter.write(product, MediaTypes.HAL_JSON, msg);
String json = msg.getBodyAsString();
log.info("{}", json);
}
}
Still, I can't understand why I have to create a HttpMessageConverter when I just want to get HAL+JSON output...
I've tried to build some basic web application using Spring 4 with Thymeleaf and I have problem with testing.
First my build.gradle dependencies:
dependencies {
compile("org.springframework:spring-webmvc:4.0.5.RELEASE")
compile("org.thymeleaf:thymeleaf-spring4:2.1.3.RELEASE")
compile 'org.springframework:spring-test:4.0.5.RELEASE'
providedCompile("javax:javaee-web-api:6.0")
testCompile("junit:junit")
testCompile ("org.mockito:mockito-all:1.9.5")
}
Next, my controller class:
package pl.com.tegess.RetrospectionSystem;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
#Controller
public class GreetingController {
#RequestMapping("/greeting")
public String greeting(#RequestParam(value="name", required=false, defaultValue="World") String name, Model model) {
model.addAttribute("name", name);
return "greeting";
}
}
and the test:
package pl.com.tegess.RetrospectionSystem;
import org.junit.Before;
import org.junit.Test;
import org.mockito.InjectMocks;
import org.mockito.MockitoAnnotations;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
import pl.com.tegess.RetrospectionSystem.configuration.WebAppConfiguration;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.forwardedUrl;
import static org.springframework.test.web.servlet.setup.MockMvcBuilders.standaloneSetup;
public class GreetingControllerTest {
private static final String greetingView = "/WEB-INF/templates/greeting.html";
MockMvc mockMvc;
#InjectMocks
GreetingController controller;
#Before
public void setup(){
MockitoAnnotations.initMocks(this);
mockMvc = standaloneSetup(controller).setViewResolvers(viewResolver()).build();
}
private InternalResourceViewResolver viewResolver() {
InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
viewResolver.setPrefix("/WEB-INF/templates/");
viewResolver.setSuffix(".html");
return viewResolver;
}
#Test
public void testGreeting() throws Exception {
mockMvc.perform(get("/greeting")).andExpect(forwardedUrl(greetingView));
}
}
And there is what i get when i run this test:
java.lang.ClassFormatError: Absent Code attribute in method that is not native or abstract in class file javax/servlet/ServletException
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(ClassLoader.java:760)
at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
at java.net.URLClassLoader.defineClass(URLClassLoader.java:455)
at java.net.URLClassLoader.access$100(URLClassLoader.java:73)
at java.net.URLClassLoader$1.run(URLClassLoader.java:367)
at java.net.URLClassLoader$1.run(URLClassLoader.java:361)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:360)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
at org.springframework.test.web.servlet.setup.MockMvcBuilders.standaloneSetup(MockMvcBuilders.java:71)
at pl.com.tegess.RetrospectionSystem.GreetingControllerTest.setup(GreetingControllerTest.java:28)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
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.RunBefores.evaluate(RunBefores.java:24)
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.runner.JUnitCore.run(JUnitCore.java:160)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:74)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:211)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:67)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:134)
Have you any idea?
Some of the test scope dependencies need to be added that will assist you in both development and testing
testCompile 'javax.el:javax.el-api:3.0.0'
testCompile 'org.glassfish.web:el-impl:2.2'
providedCompile 'javax.servlet:javax.servlet-api:3.0.1'
and you can get rid of the
providedCompile("javax:javaee-web-api:6.0")
as it downloads a lot of dependencies that would help at development time but not at testing time
I am trying to access the database through a class using PlayFremwork and writing a test
import static org.junit.Assert.*;
import javax.persistence.EntityManager;
import models.com.vlist.entity.classes.Playlist;
import org.junit.Test;
import play.db.jpa.JPA;
import play.db.jpa.Transactional;
import play.jobs.OnApplicationStart;
import play.mvc.Scope.Session;
public class PlaylistTest {
#Test
#Transactional
public void insertIntoPlaylist() {
Playlist playlist = new Playlist();
playlist.setId(1);
playlist.setName("test");
EntityManager em = JPA.em();
em.persist(playlist);
}
}
The error stacktrace is:
play.exceptions.JPAException: The JPA context is not initialized. JPA Entity Manager automatically start when one or more classes annotated with the #javax.persistence.Entity annotation are found in the application.
at play.db.jpa.JPA.get(JPA.java:22)
at play.db.jpa.JPA.em(JPA.java:51)
at PlaylistTest.insertIntoPlaylist(PlaylistTest.java:23)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:76)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:49)
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)
How can I resolve this issue while writing test?
Thank you
FIXED!! By extending FunctionalTest
public class PlaylistTest extends FunctionalTest {
#Test
#Transactional
public void insertIntoPlaylist() {
Playlist playlist = new Playlist();
playlist.setName("new_playlist_again");
EntityManager em = JPA.em();
em.persist(playlist);
}
}
public class PlaylistTest extends FunctionalTest {
#Test
#Transactional
public void insertIntoPlaylist() {
Playlist playlist = new Playlist();
playlist.setName("new_playlist_again");
EntityManager em = JPA.em();
em.persist(playlist);
}
}