Search code examples
javaspringspring-mobile

How to Junit a RestController But with Spring Mobile (spring-mobile-device)


I have a Rest controller with a Device (Device must be resolvem, I'm using spring-mobile-device) as a Parameter. The unit test gave me a status 415.

Here is the Code of

@RequestMapping(method = RequestMethod.POST)
public ResponseEntity<?> authenticationRequest(@RequestBody AuthenticationRequestDto authenticationRequest,
        Device device) throws AuthenticationException {

    Authentication authentication = this.authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(
            authenticationRequest.getUsername(), authenticationRequest.getPassword()));
    SecurityContextHolder.getContext().setAuthentication(authentication);

    UserDetails userDetails = this.userDetailsService.loadUserByUsername(authenticationRequest.getUsername());

    String token = this.tokenGenerator.generateToken(userDetails, device);

    return ResponseEntity.ok(new AuthenticationResponseDto(token));
}

Unit test

    ResultActions res = mockMvc.perform(post("/auth", authentication, device).contentType(TestUtil.APPLICATION_JSON_UTF8)
            .content(TestUtil.convertObjectToJsonBytes(authentication)));
    res.andExpect(status().isOk());

Solution

  • Well basically I was wrong with my configuration. It is mandatory configure the Web Config for testing in same way that production configuration but are grammatically different. Well I learned a lot about MockMVC config with this problem.

    Here's the solution if you want do unit testing with spring mobile.

    First Class

    @RunWith(SpringJUnit4ClassRunner.class)
    @ContextConfiguration(classes = {WebTestConfig.class})
    @WebAppConfiguration
    public class WebTestConfigAware {
    
      @Autowired
      private WebApplicationContext context;
    
      protected MockMvc mockMvc;
    
      @Autowired
      private FilterChainProxy springSecurityFilterChain;
    
      @Before
      public void setup() {
        mockMvc = MockMvcBuilders.webAppContextSetup(context).build();
        DeviceResolverRequestFilter deviceResolverRequestFilter = new DeviceResolverRequestFilter();
    
        mockMvc = MockMvcBuilders.webAppContextSetup(context)
            .addFilters(this.springSecurityFilterChain, deviceResolverRequestFilter).build();
      }
    
    }
    

    Second class

    @Configuration
    @EnableWebMvc
    @Import({RootTestConfig.class, WebCommonSecurityConfig.class})
    public class WebTestConfig  extends WebMvcConfigurerAdapter{
    
    
      @Override
      public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
        argumentResolvers.add(new ServletWebArgumentResolverAdapter(new DeviceWebArgumentResolver()));
        argumentResolvers.add(new SitePreferenceHandlerMethodArgumentResolver());
      }
    }
    

    and Test Class

    public class AuthenticationControllerTest extends WebTestConfigAware {
    
      @Test
      public void testAuthenticationRequest() throws Exception {
        AuthenticationRequestDto authentication = new AuthenticationRequestDto();
        authentication.setUsername("admin");
        authentication.setPassword("Test1234");
    
        String jsonAuthentication = TestUtil.convertObjectToJsonString(authentication);
    
        ResultActions res = mockMvc.perform(post("/auth")
            .contentType(MediaType.APPLICATION_JSON_UTF8_VALUE).content(jsonAuthentication));
    
        res.andExpect(status().isOk());
    
      }