我试图在我的spring应用程序中对控制器类进行单元测试。我为此测试付出了很多努力。我想在方法功能以及身份验证和授权方面测试我的控制器。
功能不是问题,但授权和身份验证才是问题。因为我要进行UNIT测试,所以我不希望用@SpringBootTest
注释测试类,因为这会加载整个应用程序上下文(如果我没记错的话)。因此,我决定使用@WebMvcTest
来增加安全性,而我的第一个问题是它没有考虑角色。我有受角色保护的url,而@WebMvcTest
似乎并不在乎它们。同样,在测试了所有安全的URL之后,我决定测试我的公共URL,并且在编写测试时未进行任何验证,这导致401错误。在此之后,我意识到我所有其他测试都是偶然通过的,因为实际上所有URL都受到保护,而不是我在安全配置类中设置的URL。
在线阅读后,我发现我可以将我的安全配置类作为@ContextConfiguration
批注的一部分。唯一的问题是测试无法运行,因为无法加载应用程序上下文。原因是安全性配置类包含一些用@Autowired
注释的变量。我开始在测试类中包含@MockBean
和相应的bean,并且错误开始逐渐改变,直到最终加载应用程序上下文为止。我不喜欢这样,因为我在网上找到的所有示例都没有做到这一点,并且在我的测试中只包含随机变量只是为了取悦config类,这似乎很肮脏。
我真的很困,一直在找几个小时,但对我没有任何帮助。我只是想使用我的config类而不是Spring使用的一些默认类来测试我的端点的功能,授权和身份验证。
但是,我有一个不确定的问题,也许更有经验的人可以回答我。测试授权和认证是否超出了单元测试的范围?我是否需要使用@SpringBootTest
加载整个应用程序上下文?
这是我的测试类的摘录,其中包括注释以及如何准备MockMvc:
@RunWith(SpringRunner.class)
@WebMvcTest(value = MyController.class)
@ContextConfiguration(classes = {MyController.class,SecurityConfig.class})
public class MyControllerTest {
@Autowired
private MockMvc mockMvc;
}
我的控制器类带有@Restcontroller
注释,并且所有方法都没有@PreAuthorize
或@PostAuthorize
,它们仅依赖于安全性配置文件。手动测试(通过POSTMAN调用API)时,一切正常,因此我确定这是我的测试配置问题。
这是我的安全配置类(代码段):
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
@Configuration
@Order(3)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private ClassA classA;
@Autowired
private ClassB classB;
@Autowired
private ClassC classC;
...
.antMatchers("/public/**").permitAll()
}
当我知道它应该返回200时,它会一直返回401:
@Test
public void testGetIsProductionValue() throws Exception {
MvcResult result = mockMvc.perform(get("/public/production")
.param("production", "false"))
.andExpect(status().isOk())
.andReturn();
}