You:
in Spring i can do tests @WithMockUser and a list of roles is there a way to achieve the same with parameterized tests looping through an actual list of roles instead of a single test with the combination of roles?
ChatGPT:
Yes, you can achieve this with parameterized tests by dynamically setting up each test with a single role from a list of roles. However, @WithMockUser
doesn’t directly support parameterized roles out of the box. Instead, you can use @ParameterizedTest
and programmatically create a mock user with each role in the list.Here’s how you can do it by leveraging SecurityContextHolder
to manually set up the authentication for each test:
import org.junit.jupiter.api.AfterEach
import org.junit.jupiter.api.DisplayName
import org.junit.jupiter.api.MethodSource
import org.junit.jupiter.params.ParameterizedTest
import org.junit.jupiter.params.provider.Arguments
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc
import org.springframework.boot.test.context.SpringBootTest
import org.springframework.security.authentication.TestingAuthenticationToken
import org.springframework.security.core.authority.SimpleGrantedAuthority
import org.springframework.security.core.context.SecurityContextHolder
import org.springframework.test.web.servlet.MockMvc
import org.springframework.test.web.servlet.get
import java.util.stream.Stream
@SpringBootTest
@AutoConfigureMockMvc
class YourControllerTests(@Autowired val mvc: MockMvc) {
@ParameterizedTest
@ValueSource(strings = ["ROLE_USER", "ROLE_ADMIN", "ROLE_GUEST"])
@DisplayName("Test with different roles")
fun `test with various roles`(role: String) {
mvc.perform {
get("/path/resource") {
with(SecurityMockMvcRequestPostProcessors.user("testUser").roles(role))
accept(MediaType.APPLICATION_JSON)
}
}
.andDo { print() }
.andExpect {
// Your assertions here, e.g., status { isOk() }
}
}
}
-
Set Security Context : Inside each test, manually set up the
SecurityContextHolder
with a mock authentication containing the current role. -
Clear Security Context : Use
@AfterEach
to clear the security context after each test.
This approach allows you to test each role individually in a parameterized fashion.