在不加载 spring 上下文的情况下测试 @ConfigurationProperties 注释
Testing @ConfigurationProperties annotation without loading spring context
我正在尝试测试具有 @ConfigurationProperties
注释但未加载整个 spring 上下文的 class。我尝试仅使用 JUnit5 的功能来做到这一点,但直到现在都没有成功。
我正在使用 spring-boot-starter-parent
v2.6.2 .
我正在测试的 class :
@ConfigurationProperties("db.mongo")
@AllArgsConstructor
@NoArgsConstructor
@Getter
@Setter
public class MongoProperties {
private String host;
private String db;
private String user;
private String password;
}
application.yaml :
db:
mongo:
host: localhost
db: test
user: test-user
password: secret
我的测试class:
@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());
}
}
MongoProperties
bean注入成功,但是里面的值全部为null,断言失败。
添加 @SpringBootTest
解决了 bean 实例中的空值问题,但它也启动了整个 spring 上下文,这是我不想要的。
但是使用 @ExtendWith(SpringExtension.class)
也会启动 spring 上下文。区别在于它以传统方式启动上下文,而 @SpringBootTest
以 spring-boot 方式启动它。所以无论你使用哪一个,它仍然需要启动spring上下文。
如果您关心的是在使用 @SpringBootTest
时尽量减少需要加载到 spring 上下文中的 bean 数量,您实际上可以像下面这样配置指定的 @Configuration
默认情况下 @SpringBootTest
将加载您的应用程序中定义的所有 bean,这可能对测试来说太多了(有关详细信息,请参阅 this):
@SpringBootTest
public class MongoPropertiesTest {
@Autowired
private MongoProperties properties;
@Configuration
@EnableConfigurationProperties({MongoProperties.class})
public static class Config {
}
}
如果你真的只想使用 @ExtendWith(SpringExtension.class)
,你将失去 spring-boot 功能,例如 externalising configuration features 这导致你无法从 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 {
}
}
您可以考虑进一步使用 @SpringJUnitConfig
将 @ExtendWith(SpringExtension.class)
和 @ContextConfiguration
组合在一起,从而得到:
@SpringJUnitConfig(initializers = ConfigDataApplicationContextInitializer.class)
public class MongoPropertiesTest {
@Autowired
private MongoProperties properties;
@Configuration
@EnableConfigurationProperties({MongoProperties.class})
public static class Config {
}
}
实际上这两种方法在速度方面没有太大差异,所以为了简单起见,我更喜欢只使用 @SpringBootTest
,因为它不需要您配置 ConfigDataApplicationContextInitializer
.
我正在尝试测试具有 @ConfigurationProperties
注释但未加载整个 spring 上下文的 class。我尝试仅使用 JUnit5 的功能来做到这一点,但直到现在都没有成功。
我正在使用 spring-boot-starter-parent
v2.6.2 .
我正在测试的 class :
@ConfigurationProperties("db.mongo")
@AllArgsConstructor
@NoArgsConstructor
@Getter
@Setter
public class MongoProperties {
private String host;
private String db;
private String user;
private String password;
}
application.yaml :
db:
mongo:
host: localhost
db: test
user: test-user
password: secret
我的测试class:
@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());
}
}
MongoProperties
bean注入成功,但是里面的值全部为null,断言失败。
添加 @SpringBootTest
解决了 bean 实例中的空值问题,但它也启动了整个 spring 上下文,这是我不想要的。
但是使用 @ExtendWith(SpringExtension.class)
也会启动 spring 上下文。区别在于它以传统方式启动上下文,而 @SpringBootTest
以 spring-boot 方式启动它。所以无论你使用哪一个,它仍然需要启动spring上下文。
如果您关心的是在使用 @SpringBootTest
时尽量减少需要加载到 spring 上下文中的 bean 数量,您实际上可以像下面这样配置指定的 @Configuration
默认情况下 @SpringBootTest
将加载您的应用程序中定义的所有 bean,这可能对测试来说太多了(有关详细信息,请参阅 this):
@SpringBootTest
public class MongoPropertiesTest {
@Autowired
private MongoProperties properties;
@Configuration
@EnableConfigurationProperties({MongoProperties.class})
public static class Config {
}
}
如果你真的只想使用 @ExtendWith(SpringExtension.class)
,你将失去 spring-boot 功能,例如 externalising configuration features 这导致你无法从 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 {
}
}
您可以考虑进一步使用 @SpringJUnitConfig
将 @ExtendWith(SpringExtension.class)
和 @ContextConfiguration
组合在一起,从而得到:
@SpringJUnitConfig(initializers = ConfigDataApplicationContextInitializer.class)
public class MongoPropertiesTest {
@Autowired
private MongoProperties properties;
@Configuration
@EnableConfigurationProperties({MongoProperties.class})
public static class Config {
}
}
实际上这两种方法在速度方面没有太大差异,所以为了简单起见,我更喜欢只使用 @SpringBootTest
,因为它不需要您配置 ConfigDataApplicationContextInitializer
.