我想弄清楚,什么是测试Spring Boot应用程序安全性配置的最佳方法。我的目标是进行两个测试:
在开始研究时,我发现的所有教程都指向“ MockMvc”,但我无法编写2种以这种方式工作的测试。在几乎所有情况下,我似乎都完全忽略了安全性(即使没有提供任何用户,MockMvc也会返回200)。
假设我有以下设置,作为一个简单示例:
安全配置:
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().anyRequest().authenticated().and().httpBasic();
}
}
控制器:
@RestController
public class TestController {
@GetMapping("/test")
public String getTest() {
return "hello";
}
}
特性:
spring.security.user.name=testuser
spring.security.user.password=testpassword
我可以像这样使用“ TestRestTemplate”成功测试此:
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
class DemoApplicationTests {
@Autowired
private TestRestTemplate testRestTemplate;
@Test
void when_userIsValid_should_return200() throws Exception {
String res = testRestTemplate
.withBasicAuth("testuser", "testpassword")
.getForEntity("/test", String.class)
.getBody();
Assert.assertEquals("hello", res);
}
@Test
void when_userIsInvalid_should_return401() throws Exception {
HttpStatus res = testRestTemplate
.withBasicAuth("foo", "bar")
.getForEntity("/test", String.class)
.getStatusCode();
Assert.assertEquals(HttpStatus.UNAUTHORIZED, res);
}
}
所以我的问题是:这是“前进的道路”吗?如果选择MockMvc作为工具,能否请您提供一个可行的示例?我已经尝试了30种来自Tutorials和Stackoverflow的解决方案,但都没有起作用(要么MockMvc为null,安全性被完全忽略,不再检测到Controller Method,但是我太愚蠢而无法使它们起作用:/)
先感谢您!
您可以使用它WebMvcTest
来仅初始化Controller层(它不会创建/注入所有其他定义为服务/存储库的Spring Bean,等等),但是在测试Controller逻辑时它是合适的(并且更快)。
这是一个例子
@AutoConfigureMockMvc
@RunWith(SpringRunner.class)
@WebMvcTest(controllers = MainController.class)
public class ControllerTest {
@Autowired
private MockMvc mockMvc;
//@MockBean
//Service service; // mock service dependencies if needed
@Test
public void invalidCredentials() throws Exception {
this.mockMvc
.perform(get("/test").header(HttpHeaders.AUTHORIZATION,
"Basic " + Base64Utils.encodeToString("testuser:WRONGpassword".getBytes())))
.andExpect(status().isOk());
}
谢谢你的帮助!“ .andExpect(status()。isOk())”应为“ .andExpect(status()。isUnauthorized())”,但除此之外,它可以按预期工作,非常感谢!