Unit tests in Spring MVC Rest - cast issue - java

I am developing simple Rest API app and trying to test it using this tutorial: http://memorynotfound.com/unit-test-spring-mvc-rest-service-junit-mockito/
I have implemented entire test_get_all_success unit test using my working Rest API (written in Spring MVC). Unfortunately test cannot run because of following issue.
Here is entire test file:
import java.util.Arrays;
import static org.mockito.Mockito.when;
import static org.springframework.test.web.client.match.MockRestRequestMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.test.web.servlet.MockMvc;
import static org.hamcrest.Matchers.*;
import org.junit.Before;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import static org.mockito.Mockito.*;
import org.mockito.MockitoAnnotations;
import org.springframework.http.MediaType;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(classes={MyConfigClass.class})
#WebAppConfiguration
public class ClientTest {
private MockMvc mockMvc;
#Mock
private ClientManagerImpl clientManager;
#InjectMocks
private ClientController clientController;
#Before
public void init(){
MockitoAnnotations.initMocks(this);
mockMvc = MockMvcBuilders
.standaloneSetup(clientController)
.build();
}
#Test
public void findAll_ClientsFound_ShouldReturnFoundClients() throws Exception {
Client a = ...;
Client b = ...;
when(clientManager.getClients()).thenReturn(Arrays.asList(a, b));
mockMvc.perform(get("/clients"))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8_VALUE))
.andExpect(jsonPath("$", hasSize(2)));
verify(clientManager, times(1)).getClients();
verifyNoMoreInteractions(clientManager);
}
}
NetBeans shows error in this line:
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8_VALUE))
incompatible types: RequestMatcher cannot be converted to ResultMatcher
Test cannot run because of this error. When I delete this line everything works fine and test is passed.
What am I doing wrong?

The following static import causes the conflict:
import static org.springframework.test.web.client.match.MockRestRequestMatchers.content;
MockRestRequestMatchers class is used for client-side REST testing using MockRestServiceServer, but you are testing here MVC application controllers.

Related

java.lang.IllegalStateException: Configuration error

Found that IllegalStateException is used to indicate that "a method has been invoked at an illegal or inappropriate time." Now, while doing JUnit testing I found this error. Any help?
N.B: I am beginner in Java Spring Boot Framework. So, solution can be simple one.
found multiple declarations of #BootstrapWith for test class [com.jrp.pma.controller.HttpRequestTest]: [#org.springframework.test.context.BootstrapWith(value=org.springframework.boot.test.context.SpringBootTestContextBootstrapper), #org.springframework.test.context.BootstrapWith(value=org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTestContextBootstrapper)]
package com.jrp.pma.controller;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.web.client.TestRestTemplate;
import org.springframework.boot.web.server.LocalServerPort;
import org.springframework.test.context.junit4.SpringRunner;
import static org.junit.jupiter.api.Assertions.assertEquals;
#RunWith(SpringRunner.class)
#SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
//#DataJpaTest
public class HttpRequestTest {
#LocalServerPort
private int port;
#Autowired
private TestRestTemplate restTemplate;
#Test
public void homePageReturnsVersionNumberCorrectly_thenSuccess(){
String renderHtml = this.restTemplate.getForObject("http://localhost:" + port + "/", String.class);
assertEquals(renderHtml.contains("3.3.3"), false);
}
}

MockMvc Not working when Controller is in different package (JUnit5)

package com.azry.ptm.api;
import com.azry.ptm.api.model.account.AccountDTO;
import com.azry.ptm.domain.account.Account;
import com.azry.ptm.server.services.AccountService;
import org.junit.jupiter.api.Test;
import org.mockito.Mockito;
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.boot.test.mock.mockito.MockBean;
import org.springframework.http.HttpStatus;
import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.test.web.servlet.MockMvc;
import java.util.Optional;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.mockito.ArgumentMatchers.anyLong;
#AutoConfigureMockMvc
#SpringBootTest
public class AccountControllerImplTest {
#Autowired
private MockMvc mockMvc;
#MockBean
public AccountService accountService;
#Test
public void test() throws Exception {
final long entityNo = 10;
Account expectedAccount = Account.builder()
.entityNo(entityNo)
.build();
Mockito.when(accountService.getAccountById(anyLong())).thenReturn(Optional.of(expectedAccount));
MockHttpServletResponse response = mockMvc.perform(ControllerTestHelper.makeGetRequest("account/", String.valueOf(entityNo)))
.andReturn()
.getResponse();
AccountDTO responseAccount = ControllerTestHelper.toObject(response.getContentAsString(), AccountDTO.class);
assertEquals(HttpStatus.OK.value(), response.getStatus());
assertNotNull(responseAccount);
}
}
Here is my mockMvc test. it works only when the controller is in the same module es test, otherwise, when I split the project it returns a 404 error code as no endpoint was found.
has anybody experience using mockMvc in a multi-module spring-boot app?
solved using #WebMvcTest annotation
#WebMvcTest(AccountControllerImpl.class)

Cannot resolve .andExpect() method even after implementing Stackoverflow answer

I am aware a question with the exact same title exists but the answer doesn't help me any further.
I am using WebMvcTest to test my controller class. However when it comes to comparing the result using .andExpect, my IDEA (intellij) can't resolve it.
The question with the same title as this one's solution is included in my imports and is unused. I also looked at the spring docs and used the 2 implements needed.
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
Below you will find my entire class and in this case all my imports.
package be.pxl.backend.restapi;
import be.pxl.backend.restapi.controller.UserController;
import be.pxl.backend.restapi.domain.User;
import be.pxl.backend.restapi.manager.UserManager;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.http.MediaType;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import static org.hamcrest.Matchers.*;
import static org.mockito.BDDMockito.given;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
//stackoverflow try == unused
import org.springframework.test.web.servlet.ResultActions;
#RunWith(SpringRunner.class)
#WebMvcTest(UserController.class)
public class UserControllerIntegrationTest {
#Autowired
private MockMvc mockMvc;
#MockBean
private UserManager userManager;
#Test
public void givenUser_WhenGetUser_ThenReturnUser() throws Exception{
User bjorn = new User();
bjorn.setUsername("Bjorn");
bjorn.setPassword("Wachtwoord");
bjorn.setEmail("test#email.be");
given(userManager.getUserById(1L)).willReturn(bjorn);
mockMvc.perform(get("/user/1")
.contentType(MediaType.APPLICATION_JSON)
.andExpect(status().isOk())
.andExpect(jsonPath("$", hasSize(1)))
.andExpect(jsonPath("$[0].username", is(bjorn.getUsername()))));
}
}
First of all, according to the Checkstyle, you should avoid star imports.
Secondly, you have misplaced two closing parentheses, one in contentType() and the other one in the last call of andExpect(). Below is a working code.
imports:
import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.Matchers.is;
import static org.mockito.BDDMockito.given;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import be.pxl.backend.restapi.controller.UserController;
import be.pxl.backend.restapi.domain.User;
import be.pxl.backend.restapi.manager.UserManager;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.http.MediaType;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
Note the imports are ordered as per Google Java Style.
mock test:
mockMvc.perform(get("/user/1")
.contentType(MediaType.APPLICATION_JSON))
.andExpect(status().isOk())
.andExpect(jsonPath("$", hasSize(1)))
.andExpect(jsonPath("$[0].username", is(bjorn.getUsername())));

JUnit Mockito Request and Response

I am trying to create a test for a login page using JUnit where I need to mock out dev controller.
As I used a HttpServlet in my dev environment, for testing environment it is asking for httprequest...
I went for Mock request where my file is not getting where I'm using a controller not a servlet.
Can anyone help me on this?
Below is my JUnit Controller
package com.atoc.test.controller;
import java.io.PrintWriter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
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.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.redirectedUrl;
import static org.junit.Assert.assertNotNull;
import static org.mockito.Mockito.when;
import com.atoc.test.DAO.UserTestDAO;
import com.atoc.test.service.UserTestService;
import com.bpa.qaproduct.controller.UserController;
import com.bpa.qaproduct.entity.User;
import com.bpa.qaproduct.service.UserService;
import org.apache.commons.io.FileUtils;
#RunWith(SpringJUnit4ClassRunner.class)
#WebAppConfiguration
#ContextConfiguration(locations = { "classpath:testApplicationContext.xml" })
public class UserControllerTest{
#Mock
private UserService userService;
#Mock
private HttpServletRequest request;
#Mock
private HttpServletResponse response;
#InjectMocks
private UserController userController;
private MockMvc mockMvc;
#Before
public void setup() {
MockitoAnnotations.initMocks(this);
mockMvc = MockMvcBuilders.standaloneSetup(userController).build();
}
#Test
public void testviewUserrList() throws Exception {
User user = new User();
//int value = null;
when(userService.getUserFilterCount(user)).thenReturn(20);
//mockMvc.perform(get("/todo/"));
mockMvc.perform(get("/user/viewUserList")).andExpect(status().isOk());
}
#Test
public void testloginVerification() throws Exception
{
User user = new User();
HttpServletRequest request = Mockito.mock(HttpServletRequest.class);
HttpServletResponse response = Mockito.mock(HttpServletResponse.class);
when(request.getParameter("userName")).thenReturn("me");
when(request.getParameter("password")).thenReturn("secret");
mockMvc.perform(post("/user/loginVerification"))
.andExpect(status().isOk());
System.out.println("***********"+request.getParameter("userName"));
}
}
The test case does not pass and httprequest is not passing values.
So I'm getting a NullPointerException in my running environment
I mocked out the request and response methods but I'm still getting the same error.
Passing value is not null
I'm giving some values there
setting time might be the problem
I didn't extend any Mockito in main class where I'm using inner methods
You have to provide request parameters to mockmvc instead of a request object.
#Test
public void testloginVerification() throws Exception {
User user = new User();
mockMvc.perform(post("/user/loginVerification")
.param("userName", "me")
.param("password", "secret"))
.andExpect(status().isOk());
}
Also the User object is not interacting with the other code of your test. I think you're doing something completely wrong. Can you add the code of the UserController?

Spring MVC test with MockMvc

I'm trying to run a test for testing a Spring MVC controller. The test compile and runs, but my problem is that I got a PageNotFound warning:
WARN PageNotFound - No mapping found for HTTP request with URI [/] in DispatcherServlet with name ''
My really simple test as follows:
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.view;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;
#RunWith(SpringJUnit4ClassRunner.class)
#WebAppConfiguration
#ContextConfiguration({
"classpath*:/WEB-INF/applicationContext.xml",
"classpath*:/WEB-INF/serviceContext.xml"
})
public class FrontPageControllerTest {
#Autowired
private WebApplicationContext ctx;
private MockMvc mockMvc;
#Before
public void init() {
this.mockMvc = MockMvcBuilders.webAppContextSetup(this.ctx).build();
}
#Test
public void frontPageController() throws Exception {
this.mockMvc.perform(get("/"))
.andDo(print())
.andExpect(status().isOk())
.andExpect(view().name("searchfrontpage"));
}
}
I'm 100% sure that my webapp maps to the frontpage at "/" and that the name on the view is "searchfrontpage".
Please help!
Another easier way to solve the issue is to change init to this :
mockMvc = MockMvcBuilders.standaloneSetup(new FrontPageController()).build();
My ContextConfiguration was wrong. Correct was:
#ContextConfiguration({
"file:src/main/webapp/WEB-INF/applicationContext.xml",
"file:src/main/webapp/WEB-INF/serviceContext.xml"
})
Now everything works fine.

Categories