当前位置: 首页 > 知识库问答 >
问题:

Spring Boot与MockMVC的集成测试

濮俭
2023-03-14

我有以下测试类:

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = {SpringConfiguration.class, SecurityConfiguration.class})
@IntegrationTest({"server.port=8080"})
@WebAppConfiguration
public class DemoTest {

@Autowired
private EmbeddedWebApplicationContext webApplicationContext;

private MockMvc mockMvc;

@Before
public void setUp() throws Exception {
    mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build();
}

@Test
public void testGetAccountUnauthenticated() throws Exception {
    mockMvc.perform(get("/accounts/1").accept(MediaType.APPLICATION_JSON))
            .andExpect(status().isUnauthorized());
}
}

这将导致HTTP 200而不是401。我启用了组件扫描和自动配置,并在我的SecuityConfiguration类中配置了Spring Security性,如下所示:

@Configuration
@EnableWebSecurity
@EnableWebMvcSecurity // required for use of @AuthenticationPrincipal in MVC controllers.
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {

@Override
public void configure(WebSecurity web) {
    web.debug(true);
}

@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
    //set up authentication.
}

@Override
protected void configure(HttpSecurity http) throws Exception {
    http.authorizeRequests().anyRequest().authenticated();
   // set up form login
}
}

如果我使用RestTemplate访问HTTP://localhost:8080/accounts/1,那么我将获得预期的行为(HTTP 401)。

    null

因此,我不希望手动添加安全过滤器链,因为我(不正确?)期望这“只是工作”由于自动配置魔术在Spring引导?

提前谢谢你的建议。

>

  • 没有注入FilterChainProxy的原因是我的配置设置为

    @Resource(name = AbstractSecurityWebApplicationInitializer.DEFAULT_FILTER_NAME)
    private Filter securityFilter;
    
    MockMvcBuilders.webAppContextSetup(webApplicationContext).addFilters(securityFilter)
    

    但是,我不明白为什么MockMVC会忽略筛选器,因为这对于测试请求似乎很重要,因为筛选器中可能发生任何可能影响测试结果的事情。此外,这意味着要正确地测试,我需要查找servlet上下文中的所有过滤器,建立它们的优先级/URL映射,并适当地添加它们。这似乎容易出错,而且没有必要。

  • 共有1个答案

    金承嗣
    2023-03-14

    我同意MockMVC可能更多的是用于测试控制器中的SpringMVC和自定义代码,正如@Dave-Syer所评论的那样。因此,在不利用堆栈的Servlet容器部分的情况下,如果希望同时使用您的自定义控制器代码测试spring MVC基础结构(映射到URL的控制器的正确性;输入和输出对象的映射和验证;标准控制器;您的控制器),MockMVC就会为您提供。

    但是MockMVC也有添加过滤器的方法,因此它的设计具有在所描述的测试类型中使用过滤器的可能性。有时,过滤器可能在控制器中扮演代码的功能角色,否则就无法用mockmvc进行测试。

    考虑到所有这些理论,我试图模拟我的测试的引导行为,其中过滤器将以Spring Boot方式设置,并由我的测试拾取,以便与mockvmc一起使用。下面是我最后使用的一个片段。它肯定可以得到增强,以更精确地模拟引导行为,并提取到一些自定义的mockmvcbuilder。

    @Autowired
    private WebApplicationContext wac;
    
    private MockMvc mockMvc;
    
    @Before
    public void setUp() {
        Collection<Filter> filterCollection = wac.getBeansOfType(Filter.class).values();
        Filter[] filters = filterCollection.toArray(new Filter[filterCollection.size()]);
        mockMvc = MockMvcBuilders.webAppContextSetup(wac).addFilters(filters).build();
    }
    
     类似资料:
    • 我可以有一个包含Springboot集成测试的罐子吗

    • MockMvc和RestTemplate都用于与Spring和JUnit的集成测试。 问题是:它们之间有什么区别?我们什么时候应该选择它们? 以下是两个选项的示例:

    • 我正在尝试为我的Spring项目运行集成测试,它是一个简单的get方法,用于从DB返回给定id的字符串输出。但是在Mockmvc中,我一直在Mockmvc上得到一个NullPointerException。在我的测试范围内执行。 以下是测试: 这里是控制器-输出控制器: 完全错误是:

    • Spring对MockMvc有2个设置: 独立设置 WebApplication Context安装 一般来说,MockMvc用于哪种测试?单元还是集成?或者两者兼而有之? 使用独立设置(运行在Spring应用程序上下文之外)允许您编写单元测试,而使用WebApplication Context设置您可以编写集成测试,这是对的吗?

    • 我试图使用构造函数注入依赖模式。 我想知道在集成测试类上注入JPA存储库的正确方法是什么: RepoClass 注射后的服务 测试它:(我的问题来了) SpringRunner类选项1:构造函数注入 由于控制台输出显示: 测试类应该只有一个公共零参数构造函数 SpringRunner级选项2:自动注射 我觉得它正在打破人们想要的模式。 SpringRunner类选项3:空构造函数 正如所评论的:显