Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/spring-mvc/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Spring mvc 在Spring中测试控制器时模拟Web安全依赖关系_Spring Mvc_Testing_Spring Security - Fatal编程技术网

Spring mvc 在Spring中测试控制器时模拟Web安全依赖关系

Spring mvc 在Spring中测试控制器时模拟Web安全依赖关系,spring-mvc,testing,spring-security,Spring Mvc,Testing,Spring Security,要对我的控制器进行快速测试,我想使用@WebMvcTest。我为控制器编写了服务器端单元测试。这些基本上是涉及切片Spring应用程序上下文的简单单元测试: @WebMvcTest(DemoController.class) class DemoControllerTests { @Autowired private MockMvc mockMvc; @Test @WithAnonymousUser void shouldNotHaveAccessWh

要对我的控制器进行快速测试,我想使用
@WebMvcTest
。我为控制器编写了服务器端单元测试。这些基本上是涉及切片Spring应用程序上下文的简单单元测试:

@WebMvcTest(DemoController.class)
class DemoControllerTests {

    @Autowired
    private MockMvc mockMvc;

    @Test
    @WithAnonymousUser
    void shouldNotHaveAccessWhenAnonymous() throws Exception {
        this.mockMvc.perform(get("/"))
                .andExpect(status().isUnauthorized());
    }

    @Test
    @WithMockUser(username = "pascal", roles = "USER")
    void shouldHaveAccessWithUserRole() throws Exception {
        this.mockMvc.perform(get("/hello"))
                .andExpect(status().isOk())
                .andExpect(content().string("Hello"));
    }
}
控制器如下所示:

@RestController
class DemoController {

    @GetMapping("/hello")
    public String hello() {
        return "Hello";
    }

    @PreAuthorize("hasRole('ADMIN')")
    @GetMapping("/admin")
    public String admin() {
        return "Admin";
    }

}
但是,一旦我的
WebSecurityConfig
中开始涉及更多依赖项,比如
myuserdetails服务(它本身依赖于
UserObjectRepository
),问题就开始出现了

@Autowired
public WebSecurityConfig(final MyUserDetailsService myUserDetailsService) {
    this.myUserDetailsService = myUserDetailsService;
}
当我运行测试时,Spring无法加载ApplicationContext(
NoSuchBeanDefinitionException:没有“com.example.demo.MyUserDetailsService”类型的合格bean可用

当我查看
@WebMvcTest
的文档时,这是有意义的。它说组件、服务和存储库不会自动配置。但在最后一节中,它说当使用此注释时,将自动配置Spring Security。可以使用
@AutoConfigureMockMvc
进行其他配置

在我看来,没有什么特别的事情要做,即使我想在
@AutoConfigureMockMvc
中设置
安全
配置,它在默认情况下是启用的,不推荐使用。他们提到,
secure
属性从2.1.0开始就被弃用,取而代之的是SpringSecurity的测试支持。但是我找不到关于这个主题的专用Spring安全测试支持的更多细节(我已经在测试中使用了
@WithMockUser
等)

*
*使用此批注将禁用完全自动配置,而仅应用
*与MVC测试相关的配置(即{@code@Controller}),
*{@code@ControllerAdvice},{@code@JsonComponent},
*{@code Converter}/{@code GenericConverter},{@code Filter},{@code WebMVCConfiguer}
*和{@code HandlerMethodArgumentResolver}bean,而不是{@code@Component},
*{@code@Service}或{@code@Repository}bean)。
*
*默认情况下,用{@code@WebMvcTest}注释的测试也将自动配置Spring
*安全性和{@link MockMvc}(包括对HtmlUnit WebClient和Selenium的支持
*网络驱动程序)。为了更细粒度地控制MockMVC
*可以使用{@link AutoConfigureMockMvc@AutoConfigureMockMvc}注释。
*
一般来说,这些测试都很好。他们测试控制器方法及其方法安全配置。当我添加更多的依赖项和独立的类,然后尝试将它们注入我的
WebSecurityConfig
时,问题才开始出现


我如何模拟这些依赖项,以便我的控制器测试使用切片上下文,而不是使用
@springbootest
启动整个应用程序上下文?

因此安全配置显然已加载,否则您就不必麻烦使用
@WithMockUser
等。然后您可以使用Spring的
@MockBean
对WebSecurity配置中的模拟依赖项的注释

可用于向弹簧添加模拟的注释 应用程序上下文

为了避免测试类中的重复,可以创建控制器测试扩展的抽象基类测试:

public abstract class BaseControllerTest{

   @MockBean
   private UserDetailsService userDetailsService;
}

这个案子就应该这样了。对于您需要控制行为的任何模拟bean,您可以使用标准的Mockito功能。

因此,安全配置显然已加载,否则您就不必为mockuser
等而烦恼了。然后,您可以使用Spring的
@MockBean
注释来模拟WebSecurity配置中的依赖项

可用于向弹簧添加模拟的注释 应用程序上下文

为了避免测试类中的重复,可以创建控制器测试扩展的抽象基类测试:

public abstract class BaseControllerTest{

   @MockBean
   private UserDetailsService userDetailsService;
}

这个案子就应该这样了。对于您需要控制行为的任何模拟bean,您可以使用标准的Mockito功能。

您可以添加控制器代码吗?无论如何,您可以使用
@MockBean
注释来模拟这些依赖关系:是的,我可以使用
@MockBean
模拟控制器的依赖关系,但这里不是这样。我在我的
WebSecurityConfig
中有依赖项,而不是在控制器中。正如我提到的文档所指出的,
@MockBean
在spring上下文中模拟bean,而不是在控制器中。您是否使用
@RunWith(SpringRunner.class)
运行测试,但这意味着我必须在使用安全性的每个测试中模拟来自
WebSecurityConfig
的依赖项。这意味着整个应用程序中的每个控制器。这对我来说没有意义。你能添加你的控制器代码吗?无论如何,您可以使用
@MockBean
注释来模拟这些依赖关系:是的,我可以使用
@MockBean
模拟控制器的依赖关系,但这里不是这样。我在我的
WebSecurityConfig
中有依赖项,而不是在控制器中。正如我提到的文档所指出的,
@MockBean
在spring上下文中模拟bean,而不是在控制器中。您是否使用
@RunWith(SpringRunner.class)
运行测试,但这意味着我必须在使用安全性的每个测试中模拟来自
WebSecurityConfig
的依赖项。这意味着整个应用程序中的每个控制器。这对我来说毫无意义。