I'm trying to do something similar to:
mockMvc
.perform(post("/forums/{forumId}/register", 42L)
.contentType("application/json")
.param("sendWelcomeMail", "true")
.content(objectMapper.writeValueAsString(user)))
.andExpect(status().isOk());
But the .content method has disappeared with 5.2.6, there is now what seems to be a body() function:
mockMvc
.perform(post("/conversions/ktoc")
.contentType(MediaType.APPLICATION_JSON)
.body(objectMapper.writeValueAsString(request)). /*missing method to get back to Builder*/
.andExpect(status().isOk());
Can someone assist please, all the examples I find on web all point to using content(..) method
There should be still the .content() method in Spring Test 5.2.6 according to the docs.
What might have happened to your code is that your import the reactive version of MockMvcRequestBuilders from org.springframework.mock.http.server.reactive.MockServerHttpRequest.post and this has indeed no .content() method but only .body().
So insure that your import the servlet version inside your test:
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.test.web.servlet.MockMvc;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
#WebMvcTest
class PublicControllerTest {
#Autowired
private MockMvc mockMvc;
#Test
public void testMe() throws Exception {
this.mockMvc
.perform(post("/test").content("Some content"))
.andExpect(status().isOk());
}
}
Related
I did write an application that pulls customer info.
When I run the application in postman it works fine.
But when trying to run some initial tests but it gives bean error ,
The exact same configuration with the same annotations works fine in another component .
Thanks in advance
'url' should start with a path or be a complete HTTP URL: v1/customers/2503427
java.lang.IllegalArgumentException: 'url' should start with a path or be a complete HTTP URL: v1/customers/2503427
package az.iba.ms.customer.controller;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.http.HttpStatus;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
#RunWith(SpringRunner.class)
#AutoConfigureMockMvc
#SpringBootTest
public class CustomerControllerTest {
String endpoint = "v1/customers/";
String cifs = "2503427";
#Autowired
private MockMvc mockMvc;
#Autowired
private CustomerController customerController;
#Test
public void controllerInitializedCorrectly() {
Assertions.assertThat(customerController).isNotNull();
}
#Test
public void whenValidInput_providedToCustomerQueryThenReturns200() throws Exception {
mockMvc.perform(get(endpoint + cifs)
.contentType("application/json"))
.andExpect(MockMvcResultMatchers.status().is(HttpStatus.OK.value()));
}
#Test
void whenValidNotInput_providedToCustomerQueryThenReturns400() throws Exception {
mockMvc.perform(get(endpoint)
.contentType("application/json"))
.andExpect(MockMvcResultMatchers.status().is(HttpStatus.BAD_REQUEST.value()));
}
#Test
void whenValidNotMethod_providedToCustomerQueryThenReturns405() throws Exception {
mockMvc.perform(post(endpoint + cifs)
.contentType("application/json"))
.andExpect(MockMvcResultMatchers.status().is(HttpStatus.METHOD_NOT_ALLOWED.value()));
}
}
I was fixing the same error now... Error arise because endpoint must start with /.
Change your's variable endpoint from v1/customers/ to /v1/customers/.
I've put a very simple sample project on GitHub to reproduce the problem.
The main issue is that I have a PersonController that has a PutMapping to create a new person. In order to populate the Location header with the URL to fetch that person, I add the UriComponentsBuilder as parameter for that PutMapping, as you can see here:
#PostMapping
public ResponseEntity<Person> add(#RequestBody final PersonForCreate personForCreate, UriComponentsBuilder uriComponentsBuilder) {
Person newPerson = new Person(this.people.size() + 1, personForCreate.getFirstName(), personForCreate.getLastName());
this.people.add(newPerson);
// create the URI for the "Location" header
MvcUriComponentsBuilder.MethodArgumentBuilder methodArgumentBuilder = MvcUriComponentsBuilder.fromMappingName(uriComponentsBuilder, "getById");
methodArgumentBuilder.arg(0, newPerson.getId());
URI uri = URI.create(methodArgumentBuilder.build());
return ResponseEntity.created(uri).body(newPerson);
}
This works fine when running the project. But when running a test this results in an IllegalArgumentException No WebApplicationContext. The error comes from the MvcUriComponentsBuilder.fromMappingName call, but I have no idea why.
My test looks as follows:
#ExtendWith(SpringExtension.class)
#WebMvcTest
class PersonControllerTest {
#Autowired
private PersonController personController;
#Test
void add() {
this.personController.add(new PersonForCreate("Charles", "Darwin"), UriComponentsBuilder.newInstance());
}
}
I'm not sure if passing UriComponentsBuilder.newInstance() is correct, but I've tried with other values and notice no difference.
FYI, The sample project uses Spring Boot 2.2.3 and JUnit 5, but I have the same problem using a sample project on JUnit 4.
Did you try MockMvc? The following code will be called in the same way HTTP request gets processed, as you're using #WebMvcTest, only the web layer is invoked rather than the whole context.
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.result.MockMvcResultHandlers;
import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
#WebMvcTest
class PersonControllerTest {
#Autowired
private MockMvc mockMvc;
#Test
void add() throws Exception {
//this.personController.add(new PersonForCreate("Charles", "Darwin"), uriComponentsBuilder);
this.mockMvc.perform(MockMvcRequestBuilders.post("/person")
.content("{\"firstName\": \"Charles\",\"lastName\": \"Darwin\"}").contentType(MediaType.APPLICATION_JSON))
.andDo(MockMvcResultHandlers.print())
.andExpect(MockMvcResultMatchers.status().isCreated())
.andExpect(MockMvcResultMatchers.content().string("{\"id\":4,\"firstName\":\"Charles\",\"lastName\":\"Darwin\"}"));
}
}
Spring.io/guides reference
https://spring.io/guides/gs/testing-web/
According to the tutorial Testing the Web Layer, testing that the controller has been created can be done with the following code:
#Test
public void contexLoads() throws Exception {
assertThat(controller).isNotNull();
}
but I get the following error:
The method assertThat(T, Matcher<? super T>) in the type Assert is not applicable for the arguments (HomeController)"
even with the statement:
import static org.junit.Assert.assertThat;
The code of my class is the same than the one given in the example:
package com.my_org.my_app;
import static org.assertj.core.api.Assertions.assertThat;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
#RunWith(SpringRunner.class)
#SpringBootTest
public class SmokeTest {
#Autowired
private HomeController controller;
#Test
public void contexLoads() throws Exception {
assertThat(controller).isNotNull();
}
}
If I change the assert statement to:
#Test
public void contexLoads() throws Exception {
assertNotNull(controller);
}
it works as expected.
My controller class has some Autowired objects, but since they are managed by Spring Boot it should not be an issue. Any idea of what could be wrong with assertThat(controller).isNotNull();? Thanks in advance.
You used the wrong assertThat import. You should use the following:
import static org.assertj.core.api.Assertions.assertThat;
The correct method is located in AssertJ library, not in JUnit.
This blog describes some of the test improvements in Spring Boot 1.4. Unfortunately it seems that some important informations are missing. What static import is required to use the methods get(), status() and content() from the following example?
#RunWith(SpringRunner.class)
#WebMvcTest(UserVehicleController.class)
public class UserVehicleControllerTests {
#Autowired
private MockMvc mvc;
#MockBean
private UserVehicleService userVehicleService;
#Test
public void getVehicleShouldReturnMakeAndModel() {
given(this.userVehicleService.getVehicleDetails("sboot"))
.willReturn(new VehicleDetails("Honda", "Civic"));
this.mvc.perform(get("/sboot/vehicle")
.accept(MediaType.TEXT_PLAIN))
.andExpect(status().isOk())
.andExpect(content().string("Honda Civic"));
}
}
I already found out:
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
You can use the following guide to use auto import eclipse feature for static import.
Eclipse Optimize Imports to Include Static Imports
The Exact answer to your question is following.
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
I am trying to write integration test with jersey, Spring boot 1.4 and Spring data jpa.I am able to start embedded server but getting error from jersey side , any help will be appreciated.
Integration test
import static org.assertj.core.api.Assertions.assertThat;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
import org.springframework.boot.test.web.client.TestRestTemplate;
import org.springframework.test.context.junit4.SpringRunner;
#RunWith(SpringRunner.class)
#SpringBootTest(webEnvironment=WebEnvironment.RANDOM_PORT, classes=Application.class)
public class ContactServiceIT {
#Autowired
private TestRestTemplate restTemplate;
#Autowired
private ContactDao contactDao;
#Test
public void mergeContactsTest() {
String body = this.restTemplate.getForObject("/contacts/merge", String.class);
assertThat(body).isEqualTo("contacts merged");
}
}
Contact Resource
import java.io.IOException;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.core.Response;
import org.springframework.beans.factory.annotation.Autowired;
#Path("/contacts")
public class ContactResource {
#Autowired
private ContactService contactService;
#GET
#Path("merge")
public Response mergeContacts() throws IOException {
contactService.mergeContacts();
return Response.status(Response.Status.CREATED)
.entity("contacts merged").build();
}
}
Stack trace:
java.lang.NoSuchMethodError: org.glassfish.jersey.CommonProperties.getValue(Ljava/util/Map;Ljavax/ws/rs/RuntimeType;Ljava/lang/String;Ljava/lang/Object;Ljava/lang/Class;)Ljava/lang/Object;
at org.glassfish.jersey.jackson.JacksonFeature.configure(JacksonFeature.java:73) ~[jersey-media-json-jackson-2.23.1.jar:na]
at org.glassfish.jersey.model.internal.CommonConfig.configureFeatures(CommonConfig.java:680) ~[jersey-common-2.7.jar:na]
at org.glassfish.jersey.model.internal.CommonConfig.configureMetaProviders(CommonConfig.java:610) ~[jersey-common-2.7.jar:na]
at org.glassfish.jersey.server.ResourceConfig.configureMetaProviders(ResourceConfig.java:800) ~[jersey-server-2.7.jar:na]
Please let me know if I am missing something.
Thanks.