在不加载 Spring 上下文的情况下测试 @ConfigurationProperties 注解

Jey*_*eyJ 7 java spring spring-test spring-boot junit5

我正在尝试测试一个具有注释@ConfigurationProperties但不加载整个 Spring 上下文的类。我尝试仅使用 JUnit5 的功能来做到这一点,但到目前为止还没有成功。

我正在使用spring-boot-starter-parentv2.6.2 。

我正在测试的课程:

@ConfigurationProperties("db.mongo")
@AllArgsConstructor
@NoArgsConstructor
@Getter
@Setter
public class MongoProperties {
    private String host;
    private String db;
    private String user;
    private String password;
}
Run Code Online (Sandbox Code Playgroud)

application.yaml:

db:
  mongo:
    host: localhost
    db: test
    user: test-user
    password: secret
Run Code Online (Sandbox Code Playgroud)

我的测试课:

@ExtendWith(SpringExtension.class)
@EnableConfigurationProperties({MongoProperties.class})
public class MongoPropertiesTest {

    @Autowired
    private  MongoProperties properties;

    @Test
    public void mongoPropertiesLoadedTest(){
        assertNotNull(properties.getDb());
        assertNotNull(properties.getHost());
        assertNotNull(properties.getPassword());
        assertNotNull(properties.getUser());
    }
}
Run Code Online (Sandbox Code Playgroud)

beanMongoProperties注入成功,但是里面的所有值都是 null 并且断言失败。

添加@SpringBootTest解决了 bean 实例中空值的问题,但它也启动了整个 spring 上下文,这是我不想要的。

Ken*_*han 12

但使用@ExtendWith(SpringExtension.class)也会启动 spring 上下文。不同之处在于它以传统方式启动上下文,但@SpringBootTest以 spring-boot 方式启动。所以无论你使用哪一个,仍然需要启动spring上下文。

如果您关心的是在使用时最小化需要加载到 spring 上下文中的 bean 数量@SpringBootTest,您实际上可以配置如下所示的指定@Configuration,默认情况下@SpringBootTest将加载应用程序中定义的所有 bean,这对于测试来说可能太多了(请参阅有关详细信息,请参阅):

@SpringBootTest
public class MongoPropertiesTest {

    @Autowired
    private  MongoProperties properties;

    @Configuration
    @EnableConfigurationProperties({MongoProperties.class})
    public static class Config {

    }
}
Run Code Online (Sandbox Code Playgroud)

如果你真的只想使用@ExtendWith(SpringExtension.class),你将失去 spring-boot 功能,例如外部化配置功能,这会导致你无法从文件加载属性application.properties,也不支持从YAML文件加载属性等。你必须手动配置ConfigDataApplicationContextInitializer才能启用这些功能:

@ExtendWith(SpringExtension.class)
@ContextConfiguration(initializers = ConfigDataApplicationContextInitializer.class)
public class MongoPropertiesTest {
    
    @Autowired
    private MongoProperties properties;

    @Configuration
    @EnableConfigurationProperties({MongoProperties.class})
    public static class Config {

    }

}
Run Code Online (Sandbox Code Playgroud)

您可以考虑进一步使用@SpringJUnitConfig组合@ExtendWith(SpringExtension.class)@ContextConfiguration在一起,这将为您提供:

@SpringJUnitConfig(initializers = ConfigDataApplicationContextInitializer.class)
public class MongoPropertiesTest {
    
    @Autowired
    private MongoProperties properties;

    @Configuration
    @EnableConfigurationProperties({MongoProperties.class})
    public static class Config {

    }
}
Run Code Online (Sandbox Code Playgroud)

实际上这两种方法在速度方面没有太大差异,所以@SpringBootTest为了简单起见,我更喜欢使用它,因为它不需要您进行配置ConfigDataApplicationContextInitializer