Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

@WithMockUser doesn't work in Integration Test - Spring boot

I am still getting Access Denied although my test method is annotated with @WithMockUser. Why this is not working in integration test? Everything is fine with test with @WebAppConfiguration and MockMvc.

Test Class:

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class FileUploadIntegrationTest {

    @Autowired
    private TestRestTemplate restTemplate;

    @MockBean
    private FileStorageService storageService;

    @Test
    public void classPathResourceTest() throws Exception {
        ClassPathResource resource = new ClassPathResource("/test/testFile.txt", getClass());
        assertThat(resource.exists(), is(true));
    }

    @Test
    @WithMockUser(username="tester",roles={"USER"})
    public void shouldUploadFile() throws Exception {
        ClassPathResource resource = new ClassPathResource("/test/testFile.txt", getClass());

        MultiValueMap<String, Object> map = new LinkedMultiValueMap<String, Object>();
        map.add("file", resource);
        ResponseEntity<String> response = this.restTemplate.postForEntity("/files", map, String.class);

//        assertThat(response.getStatusCode(), is(HttpStatus.OK));
        then(storageService).should().addFile((any(String.class)), any(MultipartFile.class));
    }
}

Controller class:

@RestController
@RequestMapping("/files")
@PreAuthorize(value = "hasRole('ROLE_USER')")
public class FileUploadController {

    private FileStorageService fileStorageService;
    private AuthenticationFacade authenticationFacade;

    @Autowired
    public FileUploadController(FileStorageService fileUploadService, AuthenticationFacade authenticationFacade) {
        this.fileStorageService = fileUploadService;
        this.authenticationFacade = authenticationFacade;
    }

    @ResponseBody
    @PostMapping
    public ResponseEntity<UUID> uploadFile(@RequestParam("file") MultipartFile file) {
        UUID uuid = this.fileStorageService.addFile(authenticationFacade.getAuthentication().getName(), file);
        if (uuid != null) return ResponseEntity.ok(uuid);
        else return (ResponseEntity<UUID>) ResponseEntity.badRequest();
    }

}
like image 515
Milso Avatar asked Dec 01 '16 09:12

Milso


People also ask

How do you run integration test cases in spring boot?

TestRestTemplate. As explained above, for integrating testing of a spring-boot application, we need to use @SpringBootTest. spring-boot also does provide other classes like TestRestTemplate to test the REST APIs. Like RestTemplate class, it also does have methods getForObject(), postForObject(), exchange(), etc..

What does SpringBootTest annotation do?

The @SpringBootTest annotation is useful when we need to bootstrap the entire container. The annotation works by creating the ApplicationContext that will be utilized in our tests. We can use the webEnvironment attribute of @SpringBootTest to configure our runtime environment; we're using WebEnvironment.

What is SpringBootTest WebEnvironment?

public static final SpringBootTest.WebEnvironment RANDOM_PORT. Creates a web application context (reactive or servlet based) and sets a server. port=0 Environment property (which usually triggers listening on a random port). Often used in conjunction with a @LocalServerPort injected field on the test.


1 Answers

Couldn't solve this with @WithMockUser.

You can try using the Profiles approach described here: https://stackoverflow.com/a/35192495/3010484.

like image 163
hipokito Avatar answered Sep 25 '22 08:09

hipokito