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();
}
}
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..
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.
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.
Couldn't solve this with @WithMockUser.
You can try using the Profiles approach described here: https://stackoverflow.com/a/35192495/3010484.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With