I am doing the integration tests on a REST api where all the tests work but this one.
#Test
public void deleteAllUsers_should_return_noContent() throws Exception {
//Given
//When
ResultActions resultActions = mockMvc
.perform(delete("/pair?delAll"));
//Then
resultActions
.andDo(print())
.andExpect(status().isNoContent());
}
I am expecting a 204 http status but it gets a 400. Here is the code for the method:
#RequestMapping(value = "/pair", method = RequestMethod.DELETE, params = "delAll")
public ResponseEntity<Void> deleteAllUsers() {
userRepository.deleteAll();
return new ResponseEntity<>(HttpStatus.NO_CONTENT);
}
Any ideas to what am I doing wrong?
EDIT: Found the solution just adding "=true" to these lines
#RequestMapping(value = "/pair", method = RequestMethod.DELETE, params = "delAll=true")
ResultActions resultActions = mockMvc
.perform(delete("/pair?delAll=true"));
Related
I am doing controller integration testing. A controller with a get mapping returns Flux.
#Slf4j
#RequiredArgsConstructor
#RequestMapping("journal")
public class EntryController {
private final SomeService someService;
#GetMapping
public Flux<MyEntity> getEntity(
#RequestParam(required = false) String documentId,
#RequestParam(required = false) String docNumber){
return someService.getEntities( GetEntriesRequest.builder()
.documentId(documentId)
.docNumber(docNumber).build;
}
#PostMapping
public MyEntity postNew(#RequestBody #Valid MyEntity entity) {
return someService.save(entity);
}
}
.
Initially, I tried to test it like this. (method asJson remakes the Entity created by creatingEntity method in a Json format). I'm already tested a controller with a post mapping and it works right.
#Test
void getEntriesByDocumentNumber() throws Exception {
MvcResult mvcResult = this.mockMvc.perform(post("/journal")
.contentType(MediaType.APPLICATION_JSON)
.accept(MediaType.APPLICATION_JSON)
.content(asJson(creatingEntity())))
.andDo(MockMvcResultHandlers.print())
.andExpect(status().isOk())
.andReturn();
String response = mvcResult.getResponse().getContentAsString();
String documentIdFromResponse =
JsonPath.parse(response).read("$.documentId");
this.mockMvc.perform(get("/journal")
.contentType(MediaType.APPLICATION_JSON)
.accept(MediaType.APPLICATION_JSON)
.param("documentId", documentIdFromResponse))
.andDo(MockMvcResultHandlers.print())
.andExpect(status().isOk());
I do not know how to process the response that I receive. The fact is that the response body is empty, but the method works, this can be seen in the async result. I did not find how to get the asinc result. And I can’t use JsonPath, because the body is empty.
HTTP Method = GET
Request URI = /journal
Parameters = {documentId=[1590067372983-9ce4f563-520d-42ff-bd31-5b78befaf4b1]}
Headers = [Content-Type:"application/json;charset=UTF-8", Accept:"application/json"]
Body = null
Session Attrs = {}
Async:
Async started = true
Async result = [MyEntity(documentId=1590067372983-9ce4f563-520d-42ff-bd31-5b78befaf4b1, documentNumber=100)]
Resolved Exception:
Type = null
ModelAndView:
View name = null
View = null
Model = null
FlashMap:
Attributes = null
MockHttpServletResponse:
Status = 200
Error message = null
Headers = []
Content type = null
Body =
Forwarded URL = null
Redirected URL = null
Cookies = []
I try to use WebTestClient, But this code does not work. It's falling with No bean named 'webHandler' available
#SpringBootTest
#AutoConfigureMockMvc
class ApplicationTests {
#Autowired
private MockMvc mockMvc;
WebTestClient webTestClient;
#BeforeEach
void setUp(ApplicationContext context) {
webTestClient = WebTestClient.bindToApplicationContext(context).build();
}
#Test
void getEntityTest() throws Exception {
MvcResult mvcResult = this.mockMvc.perform(post("/journal")
.contentType(MediaType.APPLICATION_JSON)
.accept(MediaType.APPLICATION_JSON)
.content(asJson(creatingEntity())))
.andDo(MockMvcResultHandlers.print())
.andExpect(status().isOk())
.andReturn();
String response = mvcResult.getResponse().getContentAsString();
String documentIdFromResponse = JsonPath.parse(response).read("$.documentId");
webTestClient.get()
.uri("journal/")
.accept(MediaType.APPLICATION_JSON)
.exchange()
.expectStatus().isOk()
.expectBody()
.jsonPath("$[0].documentId").isEqualTo(documentIdFromResponse);
}
}
I'm already find this. But I don't know how to use it
#Bean
public WebHandler webHandler() {
//implement your bean initialization here
}
I am trying to test a basic controller:
#Autowired
DAOInterface db;
#RequestMapping(value = "/postdb", method = RequestMethod.GET)
#ResponseBody
public String postdb(
#RequestParam(value = "id", required = true) String id
) {
db.addEntry(id);
return "Added " + id + ".";
}
This url works as when I access it, it adds it to a db and I get the string output as a response.
I am trying to create a simple unit test for it:
#Autowired
MockMvc mockMvc;
#MockBean
DAOInterface daoInterface;
#Test
public void shouldReturnA200() throws Exception {
mockMvc.perform(get("/postdb?id=3"))
.andExpect(status().isOk());
}
But instead I get the following
MockHttpServletRequest:
HTTP Method = GET
Request URI = /postdb
Parameters = {id=[3]}
Headers = {}
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
Not sure why I it's working whenever I try and access it but fails when running this test. I don't see any issues. Might it be because I'm not using any headers or a formal response body/view and rather just outputting a String?
EDIT = It works when I add
.contextPath("/postdb")).. not sure if that's the correct way but when I write another test and dont include any request paramters, that test gives a 200 instead of a 400 or 404....
#Autowired
DAOInterface db;
#RequestMapping(value = "/postdb", method = RequestMethod.GET)
public ResponseEntity<String> postdb(#RequestParam(required = true) String id) {
db.addEntry(id);
return new ResponseEntity<>("Added " + id + ".", HttpStatus.OK);
}
Test:
#Test
public void shouldReturnA200() throws Exception {
mockMvc.perform(get("/postdb?id=3")
.contentType(MediaType.APPLICATION_JSON)
.accept(MediaType.APPLICATION_JSON))
.andExpect(status().isOk());
}
Below is working fine for me
public class FirstWebController {
#RequestMapping(value = "/postdb", method = RequestMethod.GET)
#ResponseBody
public String postdb(#RequestParam(value = "id", required = true) String id) {
System.out.println("idddddddddddd "+id);
return "Added " + id + ".";
}
}
Test class is
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration
public class FirstWebControllerTest {
#Configuration
static class FirstWebControllerTestConfiguration {
#Bean
public FirstWebController firstWebController() {
return new FirstWebController();
}
}
#Autowired
private FirstWebController firstWebController;
private MockMvc mockMvc;
#Before
public void setup() {
mockMvc = standaloneSetup(firstWebController).build();
}
#Test
public void shouldReturnA200() throws Exception {
mockMvc.perform(get("/postdb?id=3")).andExpect(status().isOk());
}
}
Try adding query parameter as below:
#Test
public void shouldReturnA200() throws Exception {
mockMvc.perform(get("/postdb).param("id", "3"))
.andExpect(status().isOk());
}
Working on a spring boot based Rest project I have a controller like this
which calls service and service layer call dao layer. Now I am writing unit test code for controllers. when I run this the error says
java.lang.AssertionError: expected:<201> but was:<415>
I don't know where I am doing wrong:
public class CustomerController {
private static final Logger LOGGER = LogManager.getLogger(CustomerController.class);
#Autowired
private CustomerServices customerServices;
#Autowired
private Messages MESSAGES;
#Autowired
private LMSAuthenticationService authServices;
#RequestMapping(value = "/CreateCustomer", method = RequestMethod.POST)
public Status createCustomer(#RequestBody #Valid Customer customer, BindingResult bindingResult) {
LOGGER.info("createCustomer call is initiated");
if (bindingResult.hasErrors()) {
throw new BusinessException(bindingResult);
}
Status status = new Status();
try {
int rows = customerServices.create(customer);
if (rows > 0) {
status.setCode(ErrorCodeConstant.ERROR_CODE_SUCCESS);
status.setMessage(MESSAGES.CUSTOMER_CREATED_SUCCESSFULLY);
} else {
status.setCode(ErrorCodeConstant.ERROR_CODE_FAILED);
status.setMessage(MESSAGES.CUSTOMER_CREATION_FAILED);
}
} catch (Exception e) {
LOGGER.info("Cannot Create the Customer:", e);
status.setCode(ErrorCodeConstant.ERROR_CODE_FAILED);
status.setMessage(MESSAGES.CUSTOMER_CREATION_FAILED);
}
return status;
}
}
The test for the CustomerController.
public class CustomerControllerTest extends ApplicationTest {
private static final Logger LOGGER = LogManager.getLogger(CustomerControllerTest.class);
#Autowired
private WebApplicationContext webApplicationContext;
private MockMvc mockMvc;
#MockBean
private CustomerController customerController;
#Before
public void setup() {
this.mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build();
}
Status status = new Status(200,"customer created successfully","success");
String customer = "{\"customerFullName\":\"trial8900\",\"customerPhoneNumber\": \"trial8900\", \"customerEmailID\": \"trial8900#g.com\",\"alternateNumber\": \"trial8900\",\"city\": \"trial8900\",\"address\":\"hsr\"}";
#Test
public void testCreateCustomer() throws Exception {
String URL = "http://localhost:8080/lms/customer/CreateCustomer";
Mockito.when(customerController.createCustomer(Mockito.any(Customer.class),(BindingResult) Mockito.any(Object.class))).thenReturn(status);
// execute
MvcResult result = mockMvc.perform(MockMvcRequestBuilders.post(URL)
.contentType(MediaType.APPLICATION_JSON_UTF8)
.accept(MediaType.APPLICATION_JSON_UTF8)
.content(TestUtils.convertObjectToJsonBytes(customer))).andReturn();
LOGGER.info(TestUtils.convertObjectToJsonBytes(customer));
// verify
MockHttpServletResponse response = result.getResponse();
LOGGER.info(response);
int status = result.getResponse().getStatus();
LOGGER.info(status);
assertEquals(HttpStatus.CREATED.value(), status);
}
}
HTTP status 415 is "Unsupported Media Type". Your endpoint should be marked with an #Consumes (and possibly also #Produces) annotation specifying what kinds of media types it expects from the client, and what kind of media type it returns to the client.
Since I see your test code exercising your production code with MediaType.APPLICATION_JSON_UTF8, you should probably mark your endpoint as consuming and producing APPLICATION_JSON_UTF8.
Then you also need to make sure that there is nothing terribly wrong going on in your error handling, because in the process of catching the exceptions generated by your production code and generating HTTP responses, your error handling code may be generating something different, e.g. generating an error status response with a payload containing an HTML-formatted error message, which would have a content-type of "text/html", which would not be understood by your test code which expects json.
Use the below base test class for your setUp and converting json to string and string to json
#RunWith(SpringJUnit4ClassRunner.class)
#SpringBootTest(classes = Main.class)
#WebAppConfiguration
public abstract class BaseTest {
protected MockMvc mvc;
#Autowired
WebApplicationContext webApplicationContext;
protected void setUp() {
mvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build();
}
protected String mapToJson(Object obj) throws JsonProcessingException {
ObjectMapper objectMapper = new ObjectMapper();
return objectMapper.writeValueAsString(obj);
}
protected <T> T mapFromJson(String json, Class<T> clazz)
throws JsonParseException, JsonMappingException, IOException {
ObjectMapper objectMapper = new ObjectMapper();
return objectMapper.readValue(json, clazz);
}
}
Also verify that your post call has happened or not check the below sample
Mockito.doNothing().when(customerServices).create(Mockito.any(Customer.class));
customerServices.create(customer);
Mockito.verify(customerServices, Mockito.times(1)).create(customer);
RequestBuilder requestBuilder = MockMvcRequestBuilders.post(URI)
.accept(MediaType.APPLICATION_JSON).content(inputInJson)
.contentType(MediaType.APPLICATION_JSON);
MvcResult mvcResult = mvc.perform(requestBuilder).andReturn();
MockHttpServletResponse response = mvcResult.getResponse();
assertEquals(HttpStatus.OK.value(), response.getStatus());
I have a controller:
#Controller
#RequestMapping(value = "/bookForm")
public class BookFormController {
#Autowired
private BookHttpRequestParser parser;
#Autowired
private BooksService booksService;
#RequestMapping(params = "add", method = RequestMethod.POST)
public String addBook(HttpServletRequest request) {
try {
Book newBook = parser.createBookFromRequest(request);
booksService.addBook(newBook);
} catch (InvalidTypedParametersException e) {
}
return "redirect:index.html";
}
This Controller has a method for adding book to DB. Method has #RequestMapping annotation with params = "add" value.
Im trying to set this params criteria to controller unit test method:
#Test
public void addBook() throws Exception{
HttpServletRequest request = mock(HttpServletRequest.class);
Book book = new Book();
when(parser.createBookFromRequest(request)).thenReturn(book);
mockMvc.perform(post("/bookForm", "add"))
.andExpect(status().isOk())
.andExpect(view().name("redirect:index.html"));
}
Where to specify this #ResuetsMapping params value?
This:
mockMvc.perform(post("/bookForm", "add"))
doesn't work at all.
The following should work.
mockMvc.perform(post("/bookForm?add="))
use RequestBuilder requestBuilders;
object to build your request
requestBuilders = MockMvcRequestBuilders.get("URL/{Pathvariable}","PathvariableValue")
.contentType(MediaType.APPLICATION_JSON)
.header("HeaderName", HeaderValue)
.param("ParameterName", "Value")
.param("ParameterName", "Value")
.accept(MediaType.APPLICATION_JSON);
and the perfrom
mockMvc.perform(requestBuilders)
.andDo(print())
.andExpect(status().isOk())
.andReturn();
I'm trying to test my controller mapping and the response http status codes. Therefore I'm using the RequestMappingHandlerAdapter and the RequestMappingHandlerMapping.
My Controller
#Controller
#RequestMapping(value ="/user")
public class AdminSpringController {
#Autowired
public UserAdminService userService;
private final Logger log = LoggerFactory.getLogger(AdminSpringController.class);
#RequestMapping(method = RequestMethod.GET, consumes = "application/json", produces = "application/json")
#ResponseStatus(HttpStatus.OK)
public List<User> getUsers() {
log.trace("Request to get all users.");
return userService.getUsers();
}
}
and my Test class:
public class AdminSpringControllerTests {
AdminSpringController cut;
private MockHttpServletRequest request;
private MockHttpServletResponse response;
private RequestMappingHandlerAdapter adapter;
private RequestMappingHandlerMapping handlerMapping;
#Test
public void testGetSc() throws Exception{
adapter = new RequestMappingHandlerAdapter();
handlerMapping = new RequestMappingHandlerMapping();
MockHttpServletRequest request = new MockHttpServletRequest();
request.setMethod("GET");
request.setRequestURI("/user");
request.addHeader("Accept", "application/json");
MockHttpServletResponse response = new MockHttpServletResponse();
Object handler = handlerMapping.getHandler(request).getHandler();
ModelAndView mav = adapter.handle(request, response, handler);
assertNotNull(mav);
}
}
But I'm getting an NullPointerException in the row Object handler = ...
I simply want to test my mapping and then check the HTTP status codes from my response. Is this the right approach or is my test implementation totally wrong. For the tests I need to use EasyMock. As next step I wanted to test if the response status codes (response.getStatus()) is equals to SC_OK (200).
Thx for any help :)
I am using SpringMvc Test approach, mixed with EasyMock, which is a good approach.
#ContextConfiguration("ProjectFacadeTest-context.xml")
#RunWith(SpringJUnit4ClassRunner.class)
public class AdminSpringControllerTests {
...
private MockMvc mockMvc;
...
#Before
public void setUp() {
this.mockMvc = MockMvcBuilders.standaloneSetup(imageController).build();
}
EasyMock.expect(mockPersistedProjectService.getImages(EasyMock.anyLong())).andReturn(images);
EasyMock.replay(mockPersistedProjectService);
MvcResult result =
this.mockMvc.perform(get("/resources/projects/1000/images")).andExpect(content().type("application/json"))
.andExpect(status().isOk()).andReturn();
MockHttpServletResponse response = result.getResponse();
//VERIFY RESPONSE
EasyMock.verify(mockPersistedProjectService);
XML FILE
<bean id="mockArtifactService" class="org.easymock.EasyMock"
factory-method="createStrictMock" primary="true">
<constructor-arg value="com.xxxxxx.service.ArtifactService" />
</bean>