Testing POST request in client side using Mockito - java

I want to test the post method that should send a post request to "server" (So I want to mock the response from the server and check the response). Also, I want to test that the response contains http status OK in the body. Question: How should I do that with mockito?
My Post Method in the client (Client-side):
public class Client{
public static void sendUser(){
String url = "http://localhost:8080/user/add";
HttpHeaders requestHeaders = new HttpHeaders();
requestHeaders.setContentType(MediaType.APPLICATION_JSON);
requestHeaders.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));
User test = new User();
test.setName("test");
test.setEmail("a#hotmail.com");
test.setScore(205);
RestTemplate restTemplate = new RestTemplate();
HttpEntity<User> request = new HttpEntity<>(test);
ResponseEntity<String> response = restTemplate.exchange(url, HttpMethod.POST, request, String.class);
if(response.getStatusCode() == HttpStatus.OK){
System.out.println("user response: OK");
}
}
}
My Controller in another module (server-side):
#RestController
#RequestMapping("/user")
public class UserController
{
#Autowired
private UserRepository userRepository;
#PostMapping("/add")
public ResponseEntity addUserToDb(#RequestBody User user) throws Exception
{
userRepository.save(user);
return ResponseEntity.ok(HttpStatus.OK);
}
Test:
#RunWith(SpringRunner.class)
#ActiveProfiles("test")
#SpringBootTest(classes = Client.class)
#AutoConfigureMockMvc
public class ClientTest
{
private MockRestServiceServer mockServer;
#Autowired
private RestTemplate restTemplate;
#Autowired
private MockMvc mockMvc;
#Before
public void configureRestMVC()
{
mockServer =
MockRestServiceServer.createServer(restTemplate);
}
#Test
public void testRquestUserAddObject() throws Exception
{
User user = new User("test", "mail", 2255);
Gson gson = new Gson();
String json = gson.toJson(user );
mockServer.expect(once(), requestTo("http://localhost:8080/user/add")).andRespond(withSuccess());
this.mockMvc.perform(post("http://localhost:8080/user/add")
.content(json)
.contentType(MediaType.APPLICATION_JSON))
.andDo(print()).andExpect(status().isOk())
.andExpect(content().json(json));
}
}
And now i am getting this error:
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'ClientTest': Unsatisfied dependency expressed through field 'restTemplate'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'org.springframework.web.client.RestTemplate' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {#org.springframework.beans.factory.annotation.Autowired(required=true)}

Based on your Client class , would like to suggest below changes so as to make it better testable :
// class
public class Client {
/*** restTemplate unique instance for every unique HTTP server. ***/
#Autowired
RestTemplate restTemplate;
public ResponseEntity<String> sendUser() {
String url = "http://localhost:8080/user/add";
HttpHeaders requestHeaders = new HttpHeaders();
requestHeaders.setContentType(MediaType.APPLICATION_JSON);
requestHeaders.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));
User test = new User();
test.setName("test");
test.setEmail("a#hotmail.com");
test.setScore(205);
HttpEntity<User> request = new HttpEntity<>(test);
ResponseEntity<String> response = restTemplate.exchange(url, HttpMethod.POST, request, String.class);
if(response.getStatusCode() == HttpStatus.OK){
System.out.println("user response: OK");
}
return response;
}
}
And then for above we Junit as :
#RunWith(MockitoJUnitRunner.class)
public class ClientTest {
private String RESULT = "Assert result";
#Mock
private RestTemplate restTemplate;
#InjectMocks
private Client client;
/**
* any setting needed before load of test class
*/
#Before
public void setUp() {
// not needed as of now
}
// testing an exception scenario
#Test(expected = RestClientException.class)
public void testSendUserForExceptionScenario() throws RestClientException {
doThrow(RestClientException.class).when(restTemplate)
.exchange(anyString(), any(HttpMethod.class), any(HttpEntity.class), any(Class.class));
// expect RestClientException
client.sendUser();
}
#Test
public void testSendUserForValidScenario() throws RestClientException {
// creating expected response
User user= new User("name", "mail", 6609);
Gson gson = new Gson();
String json = gson.toJson(user);
doReturn(new ResponseEntity<String>(json, HttpStatus.OK)).when(restTemplate)
.exchange(anyString(), any(HttpMethod.class), any(HttpEntity.class), any(Class.class));
// expect proper response
ResponseEntity<String> response =
(ResponseEntity<String>) client.sendUser();
assertEquals(this.RESULT, HttpStatus.OK, response.getStatusCode());
}
}
Basically in your sendResponse() function, we are doing as:
// we are getting URL , creating requestHeader
// finally creating HttpEntity<User> request
// and then passing them restTemplate.exchange
// and then restTemplate is doing its job to make a HTPP connection and getresponse...
// and then we are prinnting the response... somestuff
Thus in its corresponding test we should also test only what the function is doing
since the connection is being taken care by restTemplate and you're not overriding any working of restTemplate so we should not do anything for the same...
rather just test our code/logic.
Lastly, to be sure imports looks like :
to be sure , imports will be like :
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.RestTemplate;
Hope this helps.

Full code first (explanation is below):
import static org.springframework.test.web.client.ExpectedCount.manyTimes;
import static org.springframework.test.web.client.ExpectedCount.once;
import static org.springframework.test.web.client.match.MockRestRequestMatchers.requestTo;
import static org.springframework.test.web.client.response.MockRestResponseCreators.withSuccess;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
#RunWith(SpringRunner.class)
#ActiveProfiles("test")
#SpringBootTest
#AutoConfigureMockMvc
public class MyTestClass {
MockRestServiceServer mockServer;
#Autowired
private RestTemplate restTemplate; //create a bean somewhere. It will be injected here.
#Autowired
private MockMvc mockMvc;
#Before
public void configureRestMVC(){
mockServer =
MockRestServiceServer.createServer(restTemplate);
}
#Test
public void test0() throws Exception {
//this is where you would mock the call to endpoint and and response
mockServer.expect(once(), requestTo("www.example.com/endpoint1"))
.andRespond(withSuccess());
...
//here you will actually make a call to your controller. If the service class is making a post call to another endpoint outside, that you just mocked in above statement.
this.mockMvc.perform(post("www.example2.com/example2endpoint")
.content(asJsonString(new YouCustomObjectThatYouWantToPost))
.contentType(MediaType.APPLICATION_JSON))
.andDo(print()).andExpect(status().isOk())
.andExpect(content().json(matchResponseAgainstThisObject()));
}
You would need to use #AutoConfigureMockMvc annotation. The purpose behind is is to not start the server at all, but test only the layer below that, where Spring handles the incoming HTTP request and hands it off to your controller. That way, almost the full stack is used, and your code will be called exactly the same way as if it was processing a real HTTP request, but without the cost of starting the server. To do that we will use Spring’s MockMvc, and we can ask for that to be injected for us by using the #AutoConfigureMockMvc annotation on the test class.
private MockRestServiceServer mockServer;
MockRestServiceServer is a main entry point for client-side REST testing. Used for tests that involve direct or indirect use of the RestTemplate. Provides a way to set up expected requests that will be performed through the RestTemplate as well as mock responses to send back thus removing the need for an actual server.
mockServer.expect(once(), requestTo("www.example.com/endpoint1"))
.andRespond(withSuccess());
This is where you would setup mocking to outside calls. And setup expectations as well.
this.mockMvc.perform(post("www.example2.com/example2endpoint")..
This is where you would actually make a rest/api call to your own endpoint, the one that you defined in your controller. Spring will hit your endpoint, perform all the logic that you have in your controller/service layer, and when it comes to the part of actually making a call outside, will use mockServer that you just defined above. That way, it is totally offline. You never hit the actual outside service. Also, you will append your assertions on the same mockMvc.perform method.

Related

Re-direct requests to SideEffect Utility Classes

for a spring boot application that needs to be tested below is my query.
#CustomLog
#RestController
#RequestMapping("/my_path")
public class MyController {
#GetMapping(path = "**", produces = {MediaType.APPLICATION_JSON_VALUE})
public ResponseEntity<JsonNode> fetchData(HttpServletRequest request){
... some code.....which also calls external apis.....
}
#PostMapping(path = "**", produces = {MediaType.APPLICATION_JSON_VALUE})
#ResponseBody
public ResponseEntity<Map<String, Object>> createMOI(HttpServletRequest request){
... some code.....which also calls external apis.....
}
}
My application calls an external service which now needs to be mocked.
this.webClient = WebClient.builder().baseUrl("http://localhost:9600/external_host_path")
.defaultHeader(HttpHeaders.CONTENT_TYPE,MediaType.APPLICATION_JSON_VALUE)
.build();
Mono<Pojo>responseMo = webClient.post().uri("/aGivenSubPath")
.accept(MediaType.APPLICATION_JSON).bodyValue(requestPoJo)
.retrieve().bodyToMono(Pojo.class).block();
I am calling my controller API with MVC as part of springtest
#RunWith(SpringRunner.class)
#SpringBootTest
public class MyControllerTest {
#Autowired
MyController controller;
#Before
public void setup() throws Exception {
this.mockMvc = standaloneSetup(this.controller).build();
}
#Test
public void testControl() throws Exception {
mockMvc
.perform(post("http://localhost:9600/my_path")
.contentType(MediaType.APPLICATION_JSON)
.content("{'someData':'[]'}"))
.andExpect(status().isAccepted())
.andReturn();
}
}
What I am looking for is to somehow proxy or side effect
http://localhost:9600/external_host_path
and redirect all calls made for this host to a custom Utility class which provides response based on the request params to the external host programatically.
I have seen multiple examples for mockito, wireMock, mockwebserver, mockserver etc
But most of them work on a given(static path)-when(static path called)-then(give static response).
I have many calls through out the flow and I already have the logic of the utility class to generate responses for provided request arguments.
Although I was not able to find a answer to redirect webserver request to sideEffect class,
For now atleast managing by Mockito's MockBean and Answer.
#RunWith(SpringRunner.class)
#SpringBootTest
public class MyControllerTest {
#Autowired
MyController controller;
#MockBean
MyExternalServiceClient serviceClient;
#Autowired
MySideEffectService sideEffect;
#Before
public void setup() throws Exception {
this.mockMvc = standaloneSetup(this.controller).build();
Mockito.when(serviceClient.getMethod(any(),anyBoolean())).thenAnswer((Answer) invocation -> {
Object[] args = invocation.getArguments();
Object mock = invocation.getMock();
return sideEffect.getMethod((Map<String, List<String>>) args[0], (Boolean) args[1]);
});
}
#Test
public void testControl() throws Exception {
mockMvc
.perform(post("http://localhost:9600/my_path")
.contentType(MediaType.APPLICATION_JSON)
.content("{'someData':'[]'}"))
.andExpect(status().isAccepted())
.andReturn();
}
}
Will still have a lookout for a way (Maybe TestContainers with image creation on the fly that will create a server with my mockCode, so that i can use hostname of this one and replace with existing real hostname)

Mock Feign client in Spring controller in integration test

I have a gateway controller that uses internally different services. I try to write integration test that mock feign client for the controller but it doesn't work as I expected.
I have the following Feign client:
public interface StoreManagementClient {
#RequestLine("GET /v1/stores/{storeId}")
#Headers({"Accept: application/json", "Content-Type: application/json;charset=UTF-8"})
StoreDetails getStoreDetails(#Param("storeId") String storeId);
}
Store controller:
#Validated
#Controller
#RequestMapping("${gateway.path}")
public class StoreController {
#Autowired
private StoreManagementClient storeManagementClient;
#GetMapping(value = "/stores/{storeId}", produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<StoreDetails> getStoreDetails(
#PathVariable("storeId") String storeId) {
StoreDetails details = storeManagementClient.getStoreDetails(storeId);
return ResponseEntity.ok(details);
}
}
And the integration test:
#RunWith(SpringRunner.class)
#SpringBootTest(classes = {GatewayServiceApplication.class},
webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
public class ClientIntegrationTest {
#Autowired
private StoreController storeController;
#MockBean
private StoreManagementClient storeManagementClient;
private MockClient mockClient;
#Before
public void setUp() throws Exception {
mockClient = new MockClient();
}
#Test
public void testCorrectGetStoreDetailsRequest() throws JsonProcessingException {
String storeId = "store-1";
StoreDetails storeDetails = new StoreDetails();
storeDetails.setId(storeId);
storeDetails.setType("grocery");
String response = new ObjectMapper().writeValueAsString(storeDetails);
storeManagementClient = Feign.builder()
.encoder(new JacksonEncoder())
.decoder(new JacksonDecoder())
.client(mockClient
.ok(RequestKey.builder(feign.mock.HttpMethod.GET, "/v1/stores/" + sroreId)
.headers(ImmutableMap.of(
ACCEPT, newArrayList("application/json"),
CONTENT_TYPE, newArrayList("application/json;charset=UTF-8"))).build(),
response
))
.target(new MockTarget<>(StoreManagementClient.class));
// when
ResponseEntity<StoreDetails> result = storeController.getStoreDetails(storeId);
// then
StoreDetails resultBody = result.getBody();
assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK);
assertThat(resultBody.getId()).isEqualTo(storeId);
assertThat(resultBody.getType()).isEqualTo("grocery");
}
I suppose that test should mock response according the described Feign Client. But actually it returns null.
Should I do something wrong with mocking Feign client? Probably, I mixed in one test testing Feign client and my own controller and I need to separate it and write unit-test for Feign client like Mock Feign Client example?
I would be appreciate any advice
First, you replace feign client StoreManagementClient by mock:
#MockBean
private StoreManagementClient storeManagementClient;
Then in test you lost reference to the mock and points to local object:
storeManagementClient = Feign.builder()....build();
but controller still use the mock
In Plain java, you do something like:
Client client = new Client(null);
Controller controller = new Controller(client);
client = new Client(1);
assertThat(controller.get()).isEqualTo(1)) // no no no: is equal to null
PS. I hope in future my answer will be constructive

how to fix my null ResponseEntity response in junit Mock test

I am trying to test a RestTemplate exchange with a response entity in a controller from a rest Service in another application. My Junit test is coming back with a null ResponseEntity. I have tried a couple ways with no luck. First tried using mockito to mock response methods (when...then). Second tried with Exchange matchers. I also tried to mix the two with no luck. Any help would be great. Here is my Controller response I am creating:
ResponseEntity<RestResult<List<SiteMessage>>> response = rest.exchange(getAllMessagesUrl, HttpMethod.GET,
HttpEntity.EMPTY, new ParameterizedTypeReference<RestResult<List<SiteMessage>>>() {
});
Here is my Junit Test:
#RunWith(MockitoJUnitRunner.class)
#SpringBootTest
public class MessageControllerTests {
#InjectMocks
MessageController messageController;
#Mock
RestTemplate restTemplate;
#Mock
SiteMessageService serviceMock;
#Mock
ResponseEntity<RestResult<List<SiteMessage>>> response;
private MockMvc mockMvc;
#Before
public void setUp() throws Exception {
mockMvc = MockMvcBuilders.standaloneSetup(messageController).build();
}
#Test
public void testListPage() throws Exception {
RestResult<List<SiteMessage>> result = new RestResult<>();
result.setMessage("success");
SiteMessage message1 = new SiteMessage();
SiteMessage message2 = new SiteMessage();
message1.setId("ldsf030j2ldjs");
message2.setId("ldsf0432234s");
List<SiteMessage> messageList = new ArrayList<>();
messageList.add(message1);
messageList.add(message2);
result.setResults(messageList);
when(response.getBody()).thenReturn(result);
when(response.getStatusCode()).thenReturn(HttpStatus.NOT_FOUND);
when(restTemplate.exchange(
Matchers.any(URI.class),
Matchers.eq(HttpMethod.GET),
Matchers.any(),
Matchers.<ParameterizedTypeReference<RestResult<List<SiteMessage>>>>any())
).thenReturn(response);
mockMvc.perform(get("/message/list")).andExpect(status().isOk()).andExpect(view().name("message/list"));
}
}
I am trying to return a response with a body containing a RestResult object, which has a list of messages and a message

How to mock RestTemplate in Java Spring?

public class ServiceTest {
#Mock
RestTemplate restTemplate = new RestTemplate();
#InjectMocks
Service service = new Service();
ResponseEntity responseEntity = mock(ResponseEntity.class);
#Test
public void test() throws Exception {
Mockito.when(restTemplate.getForEntity(
Mockito.anyString(),
Matchers.any(Class.class)
))
.thenReturn(responseEntity);
boolean res = service.isEnabled("something");
Assert.assertEquals(res, false);
}
I tried to test a simple test for a service including a restclient. It looks I have not Mock the RestTemplate successfully. It looks like the code get the real data not the mock one. Anyone can help me with this.
The service itself will looks as this:
public class Service{
public boolean isEnabled(String xxx) {
RestTemplate restTemplate = new RestTemplate();
ResponseEntity<String> response = restTemplate.getForEntity("someurl",String.class);
if(...)return true;
return false;
}
}
The problem is that in your isEnabled you are creating a new RestTemplate. This is wrong for two reasons, one is that you cannot mock it since you are creating a new one, and second it is good to avoid creating new objects per request. RestTemplate is thread safe and hence can be a service class member, being used across many threads.
Change your service class to something like this:
public class Service{
RestTemplate restTemplate = new RestTemplate();
public boolean isEnabled(String xxx) {
ResponseEntity<String> response = restTemplate.getForEntity("someurl",String.class);
if(...)return true;
return false;
}
}
Now that your RestTemplate has become a class member you can now properly mock through one of two ways. One, inject it using the #InjectMock, or use a setter method that you call from your test.
Since you are using InjectMock in your code we can go with that.
#RunWith(MockitoJUnitRunner.class)
public class ServiceTest {
#Mock
RestTemplate restTemplate;
#InjectMocks
#Spy
Service service;
ResponseEntity responseEntity = mock(ResponseEntity.class);
#Test
public void test() throws Exception {
Mockito.when(restTemplate.getForEntity(
Mockito.anyString(),
ArgumentMatchers.any(Class.class)
))
.thenReturn(responseEntity);
boolean res = service.isEnabled("something");
Assert.assertEquals(res, false);
}
Notice that I made a few changes. First, I removed the new RestTemplate() and new Service(). You should let mockito create those for you. By annotating them with #Mock and #Spy you will ensure that Mockito will create them for you, and more importantly, will inject the mocks into your service object.
Spring MVC's test framework has offered the class MockRestServiceServer for unit testing RESTful service code.
Here is a tutorial on its use.
If you use #Autowired, you could use MockRestServiceServer.
The below is the sample.
#Service
public class Service{
#Autowired
private RestTemplate restTemplate;
public boolean isEnabled(String xxx) {
ResponseEntity<String> response = restTemplate.getForEntity("someurl",String.class);
if(...)return true;
return false;
}
}
#Service needs to use #Autowired for creating object automatically.

Add user role to request in Spring MVC Test Framework

Started studying Spring Test MVC Framework at the office today, it looks handy, but facing some serious trouble right off the bat. Spent a few hours googling, but couldn't find anything related to my issue.
Here's my very simple test class:
import static org.hamcrest.Matchers.*;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
import static org.springframework.test.web.servlet.setup.MockMvcBuilders.webAppContextSetup;
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.web.context.WebApplicationContext;
#RunWith(SpringJUnit4ClassRunner.class)
#WebAppConfiguration
#ContextConfiguration(classes = WebAppContext.class)
public class ControllerTests {
#Autowired
private WebApplicationContext wac;
private MockMvc mockMvc;
#Before
public void setup() {
mockMvc = webAppContextSetup(wac).build();
}
#Test
public void processFetchErrands() throws Exception {
mockMvc.perform(post("/errands.do?fetchErrands=true"))
.andExpect(status().isOk())
.andExpect(model().attribute("errandsModel", allOf(
hasProperty("errandsFetched", is(true)),
hasProperty("showReminder", is(false)))));
}
}
The test reaches the following controller, but fails on first if clause thanks to not being authorized properly.
#RequestMapping(method = RequestMethod.POST, params="fetchErrands")
public String processHaeAsioinnit(HttpSession session, HttpServletRequest request, ModelMap modelMap,
#ModelAttribute(ATTR_NAME_MODEL) #Valid ErrandsModel model,
BindingResult result, JopoContext ctx) {
if (request.isUserInRole(Authority.ERRANDS.getCode())) {
return Page.NO_AUTHORITY.getCode();
}
[...]
}
How do I add a user role for the MockHttpServletRequest that gets created by MockMvcRequestBuilders.post(), so that I can get past the authority check on my controller?
I know MockHttpServletRequest has a method addUserRole(String role), but since MockMvcRequestBuilders.post() returns a MockHttpServletRequestBuilder, I never get my hands on the MockHttpServletRequest and thus cannot call that method.
Checking the Spring source, MockHttpServletRequestBuilder has no methods related to user roles, nor is the MockHttpServletRequest.addUserRole(String role) ever called in that class, so I have no idea how to tell it to add a user role into the request.
All I can think of is adding a custom filter to filter chain and calling a custom HttpServletRequestWrapper from there that provides an implementation of isUserInRole(), but that seems a little extreme for such a case. Surely the framework should offer something more practical?
I think I found an easier way
#Test
#WithMockUser(username = "username", roles={"ADMIN"})
public void testGetMarkupAgent() throws Exception {
mockMvc.perform(get("/myurl"))
.andExpect([...]);
}
You might need the following maven entry
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<version>4.0.4.RELEASE</version>
<scope>test</scope>
</dependency>
Spring MVC Test has the principal() method that allows to mock the request credentials for cases like this. This is an example of a test where some mock credentials are set:
#RunWith(SpringJUnit4ClassRunner.class)
#WebAppConfiguration
#ContextConfiguration("classpath:spring/mvc-dispatcher-servlet.xml")
public class MobileGatewayControllerTest {
private MockMvc mockMvc;
#Autowired
private WebApplicationContext wac;
#Autowired
private Principal principal;
#Autowired
private MockServletContext servletContext;
#Before
public void init() {
mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build();
}
#Test
public void testExampleRequest() throws Exception {
servletContext.declareRoles("ROLE_1");
mockMvc.perform(get("/testjunit")
.accept(MediaType.APPLICATION_JSON)
.principal(principal))
.andDo(print())
.andExpect(status().isOk())
.andExpect(content().contentType("application/json"))
.andExpect(jsonPath("$.[1]").value("test"));
}
}
and this is an example of how to create a mock principal:
#Configuration
public class SetupTestConfig {
#Bean
public Principal createMockPrincipal() {
Principal principal = Mockito.mock(Principal.class);
Mockito.when(principal.getName()).thenReturn("admin");
return principal;
}
}
You can inject a RequestPostProcessor to configure the MockHttpServletRequest before it's used in the request.
MockHttpServletRequestBuilder requestBuilder = MockMvcRequestBuilders.get("/")
.with(new RoleRequestPostProcessor("some role"));
class RoleRequestPostProcessor implements RequestPostProcessor {
private final String role;
public RoleRequestPostProcessor(final String role) {
this.role = role;
}
#Override
public MockHttpServletRequest postProcessRequest(final MockHttpServletRequest request) {
request.addUserRole(role);
return request;
}
}
There is also an easy, alternative way of setting up specific user role for a single request. It might be handy if you want to perform only a single operation as an authorized user (like set up the test fixture), and then check if user with different role can perform certain operation:
ResultActions registerNewUserAsAdmin(String username, String password) throws Exception {
final SignUpRequest signUpPayload = new SignUpRequest(username, password);
final MockHttpServletRequestBuilder registerUserRequest = post(SIGN_UP_URL)
.with(user("admin").roles("ADMIN"))
.contentType(MediaType.APPLICATION_JSON_UTF8)
.content(jsonMapper.writeValueAsString(signUpPayload));
return mockMvc.perform(registerUserRequest);
}
See SecurityMockMvcRequestPostProcessors for more details.
IF you are using Authority instead of Roles, then grant the authority in the request like below.
mockMvc.perform(
put(REQUEST_URL).param(PARM, VALUE)
.with(SecurityMockMvcRequestPostProcessors.user(USERNAME).authorities(new SimpleGrantedAuthority("ADMIN")))
.contentType(APPLICATION_FORM_URLENCODED)
)

Categories

Resources