This question already has answers here:
Spring Boot - Test for controller fails with 404 code
(10 answers)
Closed 2 years ago.
I've tried a lot but unfortunately without success. I don't understand why I can't reach my controller.I have to run this test via the standalone setup because I don't have a SpringBoot project.
This is my test class:
#RunWith(SpringJUnit4ClassRunner.class)
public class HelpPageControllerTest {
#Mock
private HelpService helpService;
private MockMvc mockMvc;
#Before
public void setUp() {
MockitoAnnotations.initMocks(this);
this.mockMvc = MockMvcBuilders
.standaloneSetup(new HelpPageController())
.build();
}
#Test
public void justATest() throws Exception {
ResultActions resultActions = mockMvc.perform(get("/help/manuals?lang=de"));
resultActions.andExpect(status().isOk());
}
}
This is my API that I'm trying to reach:
#GetMapping("/help/manuals")
public ResponseEntity<List<ManualResponseTO>> getManuals(#RequestParam String lang) {
List<ManualResponseTO> manuals;
manuals = this.helpService.getManuals(lang);
return new ResponseEntity<>(manuals, HttpStatus.OK);
}
Running the Test I get this answer:
When i go into the Debug-Mode I can see that the mockMvc is initialized, but I have also set a debug point in my controller, but this I can´t reach.
#RunWith(SpringRunner.class)
#WebMvcTest(HelpPageController.class)
public class HelpPageControllerTest {
#Autowired
private MockMvc mockMvc;
...
}
or
#RunWith(SpringRunner.class)
#WebMvcTest(HelpPageController.class)
public class HelpPageControllerTest {
private MockMvc mockMvc;
#Autowired
private HelpPageController helpPageController;
#Before
public void setUp() {
this.mockMvc = MockMvcBuilders
.standaloneSetup(helpPageController)
.build();
}
...
}
dependency
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
I got the solution. I need a test Context Configuration.
testContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
</beans>
Now I am also mocking my Service. This is the code I need:
#RunWith(MockitoJUnitRunner.class)
#ContextConfiguration(locations = "classpath*:testContext.xml")
public class HelpPageControllerTest {
private MockMvc mockMvc;
#Mock
private HelpService helpService;
#InjectMocks
private HelpPageController helpPageController;
#Before
public void setUp() {
MockitoAnnotations.initMocks(this);
this.mockMvc = MockMvcBuilders
.standaloneSetup(helpPageController)
.build();
}
#Test
public void justATest() throws Exception {
List<ManualResponseTO> manualResponseTOS = new ArrayList<>();
when(helpService.getManuals("de")).thenReturn(manualResponseTOS);
ResultActions resultActions = mockMvc.perform(get("/manuals?lang=de"));
resultActions.andExpect(status().isOk());
}
}
Related
I have a Spring application,
and I've created this test:
#RunWith(SpringRunner.class)
#SpringJUnitWebConfig(locations = {
"classpath:testDatabaseContext.xml",
"classpath:testServicesContext.xml",
"classpath:backoffice-servlet.xml"
})
public class UserControllerTests {
#Autowired
private MockMvc mockMvc;
#Before
void setup(WebApplicationContext wac) {
this.mockMvc = MockMvcBuilders.webAppContextSetup(wac).build();
}
..
}
but when I start the test I got this error:
rg.junit.runners.model.InvalidTestClassError: Invalid test class 'com.pastis.UserControllerTests':
1. Method setup() should be public
2. Method setup should have no parameters
Here an example:
RunWith(SpringJUnit4ClassRunner.class)
#WebAppConfiguration
#ContextConfiguration(classes = MyWebConfig.class)
public class CustomerControllerTest {
#Autowired
private WebApplicationContext wac;
private MockMvc mockMvc;
#Before
public void setup () {
DefaultMockMvcBuilder builder = MockMvcBuilders.webAppContextSetup(this.wac);
this.mockMvc = builder.build();
}
#Test
public void testUserController () throws Exception {
ResultMatcher ok = MockMvcResultMatchers.status()
.isOk();
MockHttpServletRequestBuilder builder = MockMvcRequestBuilders.get("/customers");
this.mockMvc.perform(builder)
.andExpect(ok);
}
}
So I explain the output of the exception:
Add the modifier public to your method setup, otherwise JUnit can't invoke it
Remove the parameter from the method, #Before, #After and such don't allow parameters.
How to setup MockMvc correctly is another question. Recent Spring and additional annotations regarding web scope initialization and -behavior leave the scope of this answer. (This also requires more clarification, for example which JDK, which Spring or Spring Boot… XML configuration, dbunit and JUnit 4 suggest a legacy context.)
#AutoConfigureRestDocs and #AutoConfigureMockMvc do not configure MockMvc correctly. Even manually configuring them do not seem to help.
I tried configuring the MockMvc and MockMvcRestDocumentationConfigurer also manually, but it did not help.
This is the current setup:
#RunWith(SpringRunner.class)
#SpringBootTest(properties= "spring.main.allow-bean-definition-overriding=true")
#AutoConfigureRestDocs
#AutoConfigureMockMvc
public class LoginLogoutTest {
#Autowired
private MockMvc mockMvc;
#Test
public void adminCanLoginLogout() throws Exception {
mockMvc.perform(formLogin().user(TestConfig.ADMIN_USERNAME).password(TestConfig.PASSWORD))
.andExpect(status().isOk())
.andExpect(authenticated().withUsername(TestConfig.ADMIN_USERNAME))
.andDo(document("login"));
mockMvc.perform(logout())
.andExpect(status().isOk())
.andExpect(unauthenticated())
.andDo(document("logout"));
}
}
I also tried configuring them with something like this:
#RunWith(SpringRunner.class)
#SpringBootTest(properties= "spring.main.allow-bean-definition-overriding=true")
public class LoginLogoutTest {
#Rule
public JUnitRestDocumentation restDocumentation = new JUnitRestDocumentation("target/generated-snippets");
private MockMvc mockMvc;
#Before
public void setUp(){
this.mockMvc = MockMvcBuilders.webAppContextSetup(this.context)
.apply(documentationConfiguration(this.restDocumentation))
.build();
}
#Test
public void adminCanLoginLogout() throws Exception {
mockMvc.perform(formLogin().user(TestConfig.ADMIN_USERNAME).password(TestConfig.PASSWORD))
.andExpect(status().isOk())
.andExpect(authenticated().withUsername(TestConfig.ADMIN_USERNAME))
.andDo(document("login"));
mockMvc.perform(logout())
.andExpect(status().isOk())
.andExpect(unauthenticated())
.andDo(document("logout"));
}
}
I am getting the following error:
java.lang.IllegalStateException: REST Docs configuration not found. Did you forget to apply a MockMvcRestDocumentationConfigurer when building the MockMvc instance?
What am I doing wrong? The error message is not very informative.
Love Spring Testing Even More With Mocking and Unit Test Assistant:
A mocked service replaces multiple dependencies
enter image description here
#Controller
#RequestMapping("/people")
public class PeopleController {
#Autowired
protected PersonService personService;
#GetMapping
public ModelAndView people(Model model) {
for (Person person: personService.getAllPeople()) {
model.addAttribute(person.getName(), person.getAge());
}
return new ModelAndView("people.jsp", model.asMap());
}
}
private MockMvc mockMvc:
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration
public class PeopleControllerTest {
#Autowired
PersonService personService;
private MockMvc mockMvc;
#Configuration
static class Config {
// Other beans
#Bean
public PersonService getPersonService() {
return mock(PersonService.class);
}
}
#Test
public void testPeople() throws Exception {
// When
ResultActions actions = mockMvc.perform(get("/people"));
}
}
I get a mistake when I want to run mockMvc
java.lang.NullPointerException
Perform the following steps:
create service mock instead of service original
("PersonServiceMock")
replace service original by service mock
#Autowired
PersonService personService;
#Autowired
PeopleController peopleController;
private MockMvc mockMvc;
#Before
public void setup() {
peopleController = new PeopleController(new personServiceMock());
mvc = MockMvcBuilders.standaloneSetup(peopleController).build();
}
#Configuration
static class Config {
// Other beans
#Bean
public PersonService getPersonService() {
return mock(PersonService.class);
}
}
#Test
public void testPeople() throws Exception {
// When
ResultActions actions = mockMvc.perform(get("/people"));
}
}
That's because you are never initialising mockMvc in your code and the point where you access it results in nullPointerException. You need to initialise it before using it, and since multiple tests in your class could be using it, best place to do it is setup() method annotated with #before. Try below:
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration
public class PeopleControllerTest {
#Autowired
PersonService personService;
#Autowired
private WebApplicationContext wac;
private MockMvc mockMvc;
#Before
public void setup() {
mockMvc = MockMvcBuilders.webAppContextSetup(wac).build();
#Configuration
static class Config {
// Other beans
#Bean
public PersonService getPersonService() {
return mock(PersonService.class);
}
}
#Test
public void testPeople() throws Exception {
// When
ResultActions actions = mockMvc.perform(get("/people"));
}
}
from the source code I see that the mockMvc doesn't have any value, thats why it hits "java.lang.NullPointerException" for this line of code :
ResultActions actions = mockMvc.perform(get("/people"));
to make it run, I think need to give value to mockMvc first.
by constructor :
#Test
public void testPeople() throws Exception {
mockMvc = new MockMvc();
// When
ResultActions actions = mockMvc.perform(get("/people"));
}
or Autowired :
#Autowired
MockMvc mockMvc
depends on the purpose of MockMvc Class
I'm new to Spring-Boot, TestNG and MockMVC, when i try to write TestNG test case it gives Null for below:
#Autowired
private WebApplicationContext webApplicationContext;
and also it gives null for
#BeforeTest
public void start()
{
mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build();
}
Also, based on previous post from stackoverflow by moving
mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build(); to #Test also the problem not resolved.
Below my code snippet
#Autowired
private WebApplicationContext webApplicationContext;
private MockMvc mockMvc;
#BeforeTest
public void setup() {
mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build();
}
#Test
public void testEmployee() throws Exception {
mockMvc.perform(get("/employee")).andExpect(status().isOk())
.andExpect(content().contentType("application/json;charset=UTF-8"))
.andExpect(jsonPath("$.name").value("emp1")).andExpect(jsonPath("$.designation").value("manager"))
.andExpect(jsonPath("$.empId").value("1")).andExpect(jsonPath("$.salary").value(3000));
}
Any link or working sample shared will be great help.
thanks
If you want to autowire WebApplicationContext, your test class should be annotated with #ContextConfiguration and #WebAppConfiguration.
You can find an example-ish here (Spring Framework's official repository).
I am testing my web-app with
#RunWith(SpringJUnit4ClassRunner.class)
#SpringApplicationConfiguration(classes = MyApp.class)
//#WebAppConfiguration
#WebIntegrationTest
public class MyTest {
private MockMvc mockMvc;
#Autowired
private WebApplicationContext webApplicationContext;
}
#Before
public void setup() throws Exception {
this.mockMvc = webAppContextSetup(webApplicationContext)
.apply(springSecurity())
.build();
}
#Test
public void someTest() throws Exception {
result = mockMvc.perform(get("/user/"));
result
.andExpect(status().isOk())
.andExpect(content().contentType(contentType))
...
}
Is it possible to observe how tests run with Filler? Or it sends without network? Is it possible to force MockMvc to use network?
Currently I see nothing in Fiddler.
Setting of
System.getProperties().put("http.proxyHost", "127.0.0.1");
System.getProperties().put("http.proxyPort", "8888");
didn't help.