Spring WebFlux Request Principal is null in test - spring-boot

We have library which provides a custom filter for our requests, which we use to write information on the request to our logs. We previously only needed servlet support, but now need to add webflux support. I've created a new WebFilter, which works as expected.
However, trying to test this new filter has been difficult. We're relying on the principal in the request for user information for the log, but during the test, it is always null. I've tried many things, including following the examples here: https://docs.spring.io/spring-security/site/docs/5.1.0.RELEASE/reference/html/test-webflux.html
My Filter:
package com.project.utils.security.request.logging.config.autoconfig;
import com.project.utils.logging.LoggingUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.server.WebFilter;
import org.springframework.web.server.WebFilterChain;
import reactor.core.publisher.Mono;
public class ReactiveRequestLoggingFilter implements WebFilter {
private static final Logger logger = LoggerFactory.getLogger(ReactiveRequestLoggingFilter.class);
#Override
public Mono<Void> filter(ServerWebExchange serverWebExchange, WebFilterChain webFilterChain) {
return serverWebExchange
.getPrincipal()
.flatMap(
principal -> {
LoggingUtil loggingUtil =
new LoggingUtil(serverWebExchange.getRequest(), principal.getName());
loggingUtil.setEvent("Http Request");
logger.info(loggingUtil.toString());
return webFilterChain.filter(serverWebExchange);
});
}
}
My Test:
package com.project.utils.security.request.logging.config.autoconfig;
import static org.springframework.security.test.web.reactive.server.SecurityMockServerConfigurers.mockUser;
import static org.springframework.security.test.web.reactive.server.SecurityMockServerConfigurers.springSecurity;
import com.project.utils.security.request.logging.config.testcontrollers.ReactiveTestController;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import org.springframework.test.web.reactive.server.WebTestClient;
#ExtendWith(SpringExtension.class)
#SpringBootTest(classes = {ReactiveTestController.class})
class ReactiveRequestLoggingFilterTest {
#Autowired ReactiveTestController controller;
ReactiveRequestLoggingFilter filter = new ReactiveRequestLoggingFilter();
#Test
void test() {
WebTestClient client =
WebTestClient.bindToController(controller)
.webFilter(filter)
.apply(springSecurity())
.configureClient()
.build()
.mutateWith(mockUser("User"));
client
.get()
.uri("/test")
.exchange()
.expectStatus()
.isOk()
.expectBody(String.class)
.isEqualTo("GET");
}
}
The controller I'm using for the test:
package com.project.utils.security.request.logging.config.testcontrollers;
import com.project.utils.security.request.logging.config.annotations.EnableReactiveRequestLogging;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Mono;
#RestController
#RequestMapping("/test")
#EnableReactiveRequestLogging
public class ReactiveTestController {
#GetMapping
Mono<ResponseEntity<String>> get() {
return Mono.just(ResponseEntity.ok("GET"));
}
}
We are using Spring Boot 2.1, which uses Spring Security 5.1. Like I said, the actual functionality works, but we need to get tests written for it, and I can't figure out how to get the principal into the request.
Thanks!

Okay, found a working solution from this answer: https://stackoverflow.com/a/55426458/1370823
My final test looked like:
package com.project.utils.security.request.logging.config.autoconfig;
import static org.springframework.security.test.web.reactive.server.SecurityMockServerConfigurers.springSecurity;
import com.project.utils.security.request.logging.config.testcontrollers.ReactiveTestController;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.reactive.WebFluxTest;
import org.springframework.security.test.context.support.WithMockUser;
import org.springframework.security.web.server.context.SecurityContextServerWebExchangeWebFilter;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import org.springframework.test.web.reactive.server.WebTestClient;
#ExtendWith(SpringExtension.class)
#ContextConfiguration(classes = {ReactiveTestController.class, ReactiveRequestLoggingFilter.class})
#WebFluxTest(controllers = {ReactiveTestController.class})
#WithMockUser(value = "Test User", username = "TestUser")
class ReactiveRequestLoggingFilterTest {
#Autowired ReactiveTestController controller;
#Autowired ReactiveRequestLoggingFilter filter;
#Test
void test() {
WebTestClient client =
WebTestClient.bindToController(controller)
.webFilter(new SecurityContextServerWebExchangeWebFilter())
.webFilter(filter)
.apply(springSecurity())
.build();
client
.get()
.uri("/test")
.exchange()
.expectStatus()
.isOk()
.expectBody(String.class)
.isEqualTo("GET");
}
}

Related

hasRole("ROLE_USER") not working in spring boot3 with springsecurity6

I have created one LoginFilter in spring boot where i have created the user authentication object and after that redirected to dashboard page
my below files are:
LoginFilter.java
import jakarta.servlet.*;
/*import org.springframework.security.web.DefaultRedirectStrategy;
import org.springframework.security.web.RedirectStrategy;*/
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.apache.commons.lang3.StringUtils;
import org.json.JSONObject;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.DefaultRedirectStrategy;
import org.springframework.security.web.RedirectStrategy;
import org.springframework.stereotype.Component;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;
import org.springframework.web.filter.GenericFilterBean;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Base64;
import java.util.Date;
import java.util.List;
#Component
public class LoginFilter extends GenericFilterBean {
private final RedirectStrategy redirectStrategy = new DefaultRedirectStrategy();
#Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException,ServletException
{
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
SimpleGrantedAuthority authority = new SimpleGrantedAuthority("ROLE_USER");
List<SimpleGrantedAuthority> updatedAuthorities = new ArrayList<SimpleGrantedAuthority>();
updatedAuthorities.add(authority);
authentication = new UsernamePasswordAuthenticationToken("myemail.gamil.com", null, updatedAuthoritie
SecurityContextHolder.getContext().setAuthentication(authentication);
this.redirectStrategy.sendRedirect((HttpServletRequest) request, (HttpServletResponse) response,"/dashboard");
}
}
WebSecurityConfigDashboard.java
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityCustomizer;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
#Configuration
public class WebSecurityConfigDashboard {
#Autowired
private LoginFilter loginFilter;
#Bean
//authentication
public UserDetailsService userDetailsService1(PasswordEncoder encoder) {
UserDetails admin = User.withUsername("user1")
.password(encoder.encode("123"))
.roles("ROLE_USER")
.build();
UserDetails user = User.withUsername("user2")
.password(encoder.encode("123"))
.roles("ROLE_USER")
.build();
return new InMemoryUserDetailsManager(admin, user);
}
#Bean
public SecurityFilterChain securityFilterChain1(HttpSecurity http) throws Exception {
http.csrf().disable().authorizeHttpRequests()
.requestMatchers("/dashboard*").hasRole("ROLE_USER")
.and()
.formLogin()
.loginPage("/login")
.defaultSuccessUrl("/dashboard")
.failureUrl("/loginError")
.and().logout()
.invalidateHttpSession(true)
.logoutSuccessUrl("/logout")
.logoutUrl("/j_spring_security_logout").and()
.sessionManagement()
.maximumSessions(12)
.expiredUrl("/logout");
http.addFilterAfter(loginFilter, UsernamePasswordAuthenticationFilter.class);
return http.build();
}
#Bean
public WebSecurityCustomizer webSecurityCustomizer1() {
return (web) -> web.ignoring().requestMatchers("/resources/images/**");
}
#Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
LoginController.java
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import java.security.Principal;
import java.text.SimpleDateFormat;
import java.util.*;
#Controller
public class LoginController {
#RequestMapping(value = "/dashboard")
public String dashboard(Model model,Principal principal,HttpServletRequest request, HttpServletResponse response)
{
System.out.println("/dashboard called:------------------------>");
System.out.println("PRINCIPAL:--------------->"+principal.getName());
return 'dashboard';
}
#RequestMapping(value = "/login", method = RequestMethod.GET)
public String login(ModelMap model) {
System.out.println("/login called:------------------------>");
return "login";
}
#RequestMapping(value = "/logout", method = RequestMethod.GET)
public String logout(ModelMap model) {
System.out.println("/logout called:------------------------>");
return "logout";
}
#RequestMapping(value = "/loginError", method = RequestMethod.GET)
public String loginError(ModelMap model) {
model.addAttribute("error", "LOGIN FAILED");
return "login";
}
#RequestMapping(value = "/error", method = RequestMethod.GET)
public String error(ModelMap model,HttpServletRequest request, HttpServletResponse response) {
return "error";
}
}
when I calling /dashboard url in browser the it goes to login page instead of dashboard i have created UsernamePasswordAuthenticationToken in filter class.
If i remove .hasRole("ROLE_USER") and instead put .permitAll() and then if I hit /dashboard then the method with /dashboard is called but principle object getting null
I have using spring boot 3 with spring security 6
I dont't know why this is happening?
A common oversight is that roles() and hasRole() will add the ROLE_ prefix for you.
So, instead of doing hasRole('ROLE_USER'), please do hasRole('USER'). And instead of doing roles('ROLE_USER') when creating the user, do roles('USER').
I've added a Spring Security ticket to clarify this.

How do session time out and and ask for login again in Spring boot

I am trying to build simple JSON rest API using spring boot, I have build the application it works fine, now I need to do the simple Basic authentication and I did this with Spring security. Please find the Code below, My pain point here is when I run the application, I ask for the login first time then I tried to reload the URL again it does not ask for user name password. How to make the URL session expired and ask to prompt for login again. Note : I am not using any UI, It just an API
Security Configuration Class
package com.erplogic.erp.topcon.security;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.session.SessionRegistry;
import org.springframework.security.core.session.SessionRegistryImpl;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import org.springframework.security.web.SecurityFilterChain;
#Configuration
public class SecurityConfiguration {
#Bean
SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http.authorizeHttpRequests((authz) -> authz.anyRequest().authenticated()
).sessionManagement(session -> session
.sessionCreationPolicy(SessionCreationPolicy.NEVER)
)
.httpBasic();
return http.build();
}
#Bean
InMemoryUserDetailsManager userDetailsService() {
UserDetails user = User.builder().username("user").password(encoder().encode("pass")).roles("USER").build();
return new InMemoryUserDetailsManager(user);
}
#Bean
PasswordEncoder encoder() {
return new BCryptPasswordEncoder();
}
#Bean
SessionRegistry sessionRegistry() {
return new SessionRegistryImpl();
}
}
Controller Class
package com.erplogic.erp.topcon.controller;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import com.erplogic.erp.topcon.service.SapApiService;
import com.erplogic.poc.objects.Root;
import com.fasterxml.jackson.core.JsonProcessingException;
import io.erplogic.maven.plclog.wsdl2java.StandardFaultMessage_Exception;
#RestController
public class OutboundController {
#Autowired
private SapApiService sapApiService;
#RequestMapping(path ="/outbound",produces = MediaType.APPLICATION_JSON_VALUE,method = RequestMethod.GET)
public Root getOutbound() throws KeyManagementException, NoSuchAlgorithmException, StandardFaultMessage_Exception, JsonProcessingException {
return ((SapApiService) sapApiService).processOutboudService();
}
#RequestMapping(value = "/outbound/{outboundId}",produces = MediaType.APPLICATION_JSON_VALUE,method = RequestMethod.GET)
public String getOutboundId(#PathVariable String outboundId) throws KeyManagementException, JsonProcessingException, NoSuchAlgorithmException, StandardFaultMessage_Exception {
return ((SapApiService) sapApiService).processOutboudServiceByID(outboundId);
}
}

Spring boot Kafka integration test: Consumer always returns 0 records

For the following test I am always getting the error:
org.opentest4j.AssertionFailedError: expected: 10 but was : 0
What exactly I am trying to verify in scope of the test:
I am trying to send 10 messages to Kafka and after that immediately I am trying to read those messages from Kafka, but for some unknown reason KafkaConsumer returns 0 records, and I am struggling to understand why Consumer can't read messages that were sent earlier?
import lombok.extern.slf4j.Slf4j;
import org.apache.kafka.clients.consumer.ConsumerConfig;
import org.apache.kafka.clients.consumer.ConsumerRecords;
import org.apache.kafka.clients.consumer.KafkaConsumer;
import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.kafka.KafkaProperties;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.ContextConfiguration;
import java.time.Duration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ExecutionException;
import java.util.stream.IntStream;
#SpringBootTest
#ActiveProfiles("test")
#ContextConfiguration(initializers = TestKafkaContextInitializer.class)
#Slf4j
public class KafkaFlowVerificationITest {
#Autowired
private KafkaTemplate<String, String> kafkaTemplate;
#Autowired
private KafkaProperties kafkaProperties;
private final String kafkaTopic = "test.topic";
#Test
void testKafkaFlow() {
IntStream.range(0, 10)
.forEach(e -> {
try {
kafkaTemplate.send(kafkaTopic, UUID.randomUUID().toString()).get();
} catch (InterruptedException | ExecutionException ex) {
ex.printStackTrace();
}
});
checkKafkaForMessage();
}
private void checkKafkaForMessage() {
Map<String, Object> properties = new HashMap<>();
properties.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, kafkaProperties.getBootstrapServers());
properties.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, org.apache.kafka.common.serialization.StringDeserializer.class);
properties.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, org.apache.kafka.common.serialization.StringDeserializer.class);
properties.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, "earliest");
properties.put(ConsumerConfig.ENABLE_AUTO_COMMIT_CONFIG, "false");
properties.put(ConsumerConfig.GROUP_ID_CONFIG, "acme");
KafkaConsumer<String, String> consumer = new KafkaConsumer<>(properties);
consumer.subscribe(List.of(kafkaTopic));
ConsumerRecords<String, String> records = consumer.poll(Duration.ZERO);
Assertions.assertThat(records.count()).isEqualTo(10);
}
}
and TestKafkaContextInitializer:
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.test.util.TestPropertyValues;
import org.springframework.context.ApplicationContextInitializer;
import org.springframework.context.ConfigurableApplicationContext;
import org.testcontainers.containers.KafkaContainer;
import org.testcontainers.utility.DockerImageName;
#Slf4j
public class TestKafkaContextInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {
private final KafkaContainer kafkaContainer =
new KafkaContainer(DockerImageName.parse("confluentinc/cp-kafka:5.4.3"));
#Override
public void initialize(ConfigurableApplicationContext configurableApplicationContext) {
kafkaContainer.start();
var values = TestPropertyValues.of(
"spring.kafka.producer.bootstrap-servers=" + kafkaContainer.getBootstrapServers(),
"spring.kafka.consumer.bootstrap-servers=" + kafkaContainer.getBootstrapServers()
);
values.applyTo(configurableApplicationContext);
}
}
The root cause of the issue is:
I set TestContainer Kafka bootstrap server url for the following properties:
spring.kafka.producer.bootstrap-servers
spring.kafka.consumer.bootstrap-servers
but in the test I use:
spring.kafka.bootstrap-servers property, that why Consumer made attempt connect to localhost:9092 default URL instead of URL provided by TestContainer.

How do you setup a resource server in spring boot that only uses role from the jwt token to allow access?

I think I have some odd requirements here because no matter where I look, I can't a specific example for what I was asked to do. I created a dummy project called contacts to test this. I am suppose to secure my api with Oauth2, but the authorization server is not on the same box.
It is my understanding that the client will need to call the authorization to get a token and then the request with the token will be sent to my api.
In my server the scope will determine if the user has access. I am not doing any authentication on my server.
I can't seem to get this to work though.
Controller
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
#RestController
#RequestMapping(value = "/contacts")
#PreAuthorize("#oauth2.hasScope('ec.edm.mdm')")
public class ContactsController {
#Autowired
ContactRepository customerRepo;
#RequestMapping(method = RequestMethod.GET, produces = { "application/json" })
public Page<Contact> findAllContacts(Pageable pagable) {
return customerRepo.findAll(pagable);
}
}
Application
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Profile;
import org.springframework.core.env.Environment;
import org.springframework.security.access.expression.method.MethodSecurityExpressionHandler;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.method.configuration.GlobalMethodSecurityConfiguration;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
import org.springframework.security.oauth2.provider.expression.OAuth2MethodSecurityExpressionHandler;
#EnableResourceServer
#SpringBootApplication
public class App {
private static final Logger LOG = LoggerFactory.getLogger(App.class);
#Autowired
private Environment environment;
public static void main(String[] args) throws Exception {
SpringApplication.run(App.class, args);
}
/**
* Allows for #PreAuthorize annotation processing.
*/
#EnableGlobalMethodSecurity(prePostEnabled = true)
protected static class GlobalSecurityConfiguration extends GlobalMethodSecurityConfiguration {
#Override
protected MethodSecurityExpressionHandler createExpressionHandler() {
return new OAuth2MethodSecurityExpressionHandler();
}
}
}

Spring controller tests with mocks

So I'm having some issues coming up with a solution for a test.
This is the method I want to test(I'm new to this). It clears all fields on a web page each time it's loaded.
#RequestMapping("/addaddressform")
public String addAddressForm(HttpSession session)
{
session.removeAttribute("firstname");
session.removeAttribute("surname");
session.removeAttribute("phone");
session.removeAttribute("workno");
session.removeAttribute("homeno");
session.removeAttribute("address");
session.removeAttribute("email");
return "simpleforms/addContact";
}
and here's what i have so far for the test
package ControllerTests;
import java.text.AttributedCharacterIterator.Attribute;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mock.web.MockHttpSession;
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.MvcResult;
import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.result.MockMvcResultHandlers;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
#RunWith(SpringJUnit4ClassRunner.class)
#WebAppConfiguration
#ContextConfiguration (classes = {SimpleFormsControllerTest.class})
public class SimpleFormsControllerTest {
#Autowired
private WebApplicationContext wac;
private MockMvc mockMvc;
#Before
public void setup() {
this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build();
}
#Test
public void addAddressForm_ExistingContactDetailsInForm_RemovalFromSession() throws Exception{
MockHttpSession mockSession = new MockHttpSession();
mockSession.putValue("firstname", "test");
mockSession.putValue("surname", "test");
mockSession.putValue("phone", "test");
mockSession.putValue("workno", "test");
mockSession.putValue("homeno", "test");
mockSession.putValue("address", "test");
mockSession.putValue("email", "test");
mockMvc.perform(get("simpleForms/addaddressform").session(mockSession));
}
As this is the first time I've ever had to do this kind of thing I don't have much clue where to go with this.
Then you have to do is only assert the values, e.g.:
assertNull(mockSession.getAttribute("firstname"));
If you want to make sure it is the case, you can do:
assertNotNull(mockSession.getAttribute("firstname"));
before you fire the GET request.

Resources