【问题标题】:@WebMvcTest with @Autowire Constructor in WebConfig@WebMvcTest 与 WebConfig 中的 @Autowire 构造函数
【发布时间】:2020-11-09 09:56:18
【问题描述】:

我想测试一个 Spring RestController。这个项目中有一个带有@Autowired Constructor 的Web Config,它应该使用application-{environment}.yml 文件中的环境变量初始化一个ConfigurationPropertie。由于我已经实现了这个,我的应用程序运行正常,但控制器的 WebMvcTest 失败并出现以下错误:

Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'webConfig': Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.project.onlineDate.shared.entity.OriginAllowedUrisProperties' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}

代码第 1 部分:EnvironmentPropertie 类

@Configuration
@Component
@ConfigurationProperties(prefix = "origins")
public class OriginAllowedUrisProperties {

    String[] allowedUris;

    //Getter and Setter
}

代码第 2 部分:WebConfig

@Configuration
public class WebConfig implements WebMvcConfigurer {

    private final
    OriginAllowedUrisProperties originAllowedUrisProperties;

    @Autowired
    public WebConfig(OriginAllowedUrisProperties originAllowedUrisProperties) {
        this.originAllowedUrisProperties = originAllowedUrisProperties;
    }

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                .allowedOrigins(
                        originAllowedUrisProperties.getAllowedUris());
    }

}

代码第 3 部分:WebMvcTest

@ExtendWith(SpringExtension.class)
@WebMvcTest(OnlineDateController.class)
class TestOnlineDateController {

    [...]

    @MockBean
    private OnlineDateService onlineDateService;

    @Autowired
    private MockMvc mockMvc;

    @Test
    void testGetOnlineDate() throws Exception {

        when(onlineDateService.findOnlineDates().thenReturn(
                Collections.singletonList(new OnlineDate()));

        mockMvc.perform(
                get("/onlineDates")
                        .accept(MediaType.APPLICATION_JSON))
                .andExpect(status().isOk())
                .andExpect(JSON_ONLINE_DATE_MATCHER)
                .andDo(print());
    }
}

尝试修复

例如,我尝试使用 @ContextConfiguration(classes = {WebConfig.class}) 声明类级别的上下文配置,并且尝试使用 @Filter 声明排除配置。我还尝试了很多使用 OriginAllowedUrisProperties.class 以另一种方式加载环境变量,但没有任何效果。我错过了什么?你有想法吗?提前致谢。

【问题讨论】:

  • 你的 @SpringBootApplication 注释类是什么样的?
  • 类用@SpringBootApplication注解。由于我们有多个变体来获取配置变量,因此我决定用 @Component 注释 OriginAllowedUrisProperties 类,以免使 Main 类过于混乱。参考:Baeldung
  • 当您使用切片测试时,只会加载应用程序的一部分。您还需要为 OriginAllowedUrisProperties 提供模拟。 (此外,它既是@Component 又是@Configuration 也很奇怪。
  • 我试过这个。但是当我以以下方式模拟类时,当调用getAllowedUris() 方法时,返回一个String[] 我得到一个NullPointerException。可能是因为WebConfig(使用方法的地方)需要在 WebMvcTest 之前调用来创建上下文。感谢您的回答。你在最后一点是对的。我删除了@Component 注释。
  • 你可以试试@WebMvcTest({OnlineDateController.class, OriginAllowedUrisProperties.class })。另外,根据要求,您能否添加您的 @SpringBootApplication 注释类。

标签: java spring unit-testing environment-variables


【解决方案1】:

在为此苦苦挣扎之后,我想分享我的解决方案。希望这将帮助面临同样挑战的其他人。经过多次尝试,我现在已经以不同的方式解决了它。

我的解决方案:

我将 bean 声明从实体中提取出来,并直接在 Web 控制器中进行。项目中的其他任何地方都不需要此信息,因此我可以保留所有测试类。以下是代码组件,我与上面的对比有所更改。

代码第 1 部分:EnvironmentProperty 类

  • 删除了 Spring 注解
public class OriginAllowedUrisProperties {

    String[] allowedUris;

    //Getter and Setter
}

代码第 2 部分:WebConfig

  • WebConfig 中的@Bean 方法上绑定@ConfigurationProperties,以将外部化属性绑定到OriginAllowedUrisProperties
@Configuration
public class WebConfig implements WebMvcConfigurer {

    @Bean
    @ConfigurationProperties(prefix = "origins")
    public OriginAllowedUrisProperties originAllowedUrisProperties() {
        return new OriginAllowedUrisProperties();
    }

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                .allowedOrigins(originAllowedUrisProperties().getAllowedUris());
    }

}

【讨论】:

    猜你喜欢
    • 2014-10-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-10
    • 1970-01-01
    • 1970-01-01
    • 2011-10-08
    • 1970-01-01
    相关资源
    最近更新 更多