如何在 Spring Boot 测试中加载仅添加命名组件的基本 Spring Application-Context?
Posted
技术标签:
【中文标题】如何在 Spring Boot 测试中加载仅添加命名组件的基本 Spring Application-Context?【英文标题】:How to Load, in Spring Boot Test, Basic Spring Application-Context Adding Only Named Components? 【发布时间】:2021-12-31 23:34:09 【问题描述】:原创
我正在尝试在 Spring Boot (v2.3.8) 应用程序的测试中加载 基本 Spring 应用程序上下文中的仅命名 组件。更具体地说,我想在测试中加载一个 Spring 应用程序上下文,它至少配置日志记录、外部属性的加载、验证(通过 Java Validation API)和@Value
-plugging 但没有 MVC、Data JPA 等. 本质上,我想通过一个带约束注释的接口(例如@NotBlank
)来测试一个只使用本地文件系统的@Service
(没有MVC、Data JPA或任何其他Spring Boot Test“切片” ) 并通过@Value
填充一个数据成员。
我在不同的组合子集中尝试了许多注释(以及它们的一些固有属性),但无济于事:例如@SpringBootTest
、@Configuration
、@ContextConfiguration
、@TestConfiguration
、@TypeExcludeFilters
等。例如:
@Validated
public interface SomeService
String someMethod (@NotBlank String someParam);
...
@Service
public class SomeServiceImpl implements SomeService
@Value("$some.value")
private String someValue;
@Override
public String someMethod(String someParam)
// do something with local file-system,
// with someValue in hand, and
// knowing someParam not blank
...
@SpringBootTest(classes=SomeServiceImpl.class,webEnvironment=WebEnvironment.NONE)
class SomeServiceTests
@Autowired
private SomeService someService;
@Test
void throwConstraintViolationException_whenSomeParamNil()
assertThrows(
ConstraintViolationException.class,
()->someService.someMethod(new String()));
...
在此示例中,@SpringBootTest
的属性 classes
加载了引用的类,但隐藏了我也在寻找的所有基础知识(日志记录、验证等)。
以下摘录来自 Craig Walls 的“Spring Boot in Action”,似乎正是我正在寻找的,但它的主要工具 (@SpringApplicationConfiguration
) 现在已弃用(及其官方推荐的替换 - @SpringBootTest
- 表现不一样,至少在属性 classes
) 方面:
尽管@ContextConfiguration 在加载 Spring 应用方面做得很好 上下文,它不会使用完整的 Spring Boot 处理加载它... SpringApplication 不仅加载应用程序上下文,还启用日志记录,加载外部 属性(application.properties 或 application.yml),以及 Spring 的其他特性 开机。如果您使用 @ContextConfiguration,您将无法获得这些功能。要在集成测试中恢复这些功能,您可以将 @ContextConfiguration 替换为 Spring Boot 的 @SpringApplicationConfiguration:
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes=AddressBookConfiguration.class)
public class AddressServiceTests
...
在那里,他得到了“完整的 Spring Boot 处理”,但仅添加了他引用的类 (@Service
)(不是他的每个 @Component
、@Controller
和 @Repository
域)。
如果不弃用@SpringApplicationConfiguration
,今天该怎么做?
更新
我最初声明我的(不是 Craig Walls 的)示例(即 @SpringBootTest(classes=SomeServiceImpl.class,webEnvironment=WebEnvironment.NONE)
,虽然它加载了引用的类,但模糊了 Spring Boot 通常会使用的应用程序上下文的所有基础通过进一步的实验,我发现该陈述是不准确的,因为不是全部,而是只有一些的基础知识被掩盖了,即验证(Java的实现Validation API)。换句话说,日志记录、外部属性的加载和@Value-plugging 确实是加载/配置的。我想我一定是搞糊涂了,在我的所有排列/尝试中。
【问题讨论】:
【参考方案1】:经过更多的实验,我找到了答案。我不能说这是否是最好的答案,但它很简洁,而且肯定能解决问题......
import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
import org.springframework.boot.autoconfigure.validation.ValidationAutoConfiguration;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
// automatically configures validation (implementation of Java Validation API)
@ImportAutoConfiguration(ValidationAutoConfiguration.class)
// obscures/disables any otherwise-automatic web-environment;
// automatically configures logging, loading of external properties, and @Value-plugging;
// and, beyond that, adds to application-context only _cited_ classes/configuration-classes
@SpringBootTest(classes=SomeServiceImpl.class,webEnvironment=WebEnvironment.NONE)// full context loaded, if unqualified
public class SomeServiceTests
...
【讨论】:
以上是关于如何在 Spring Boot 测试中加载仅添加命名组件的基本 Spring Application-Context?的主要内容,如果未能解决你的问题,请参考以下文章
使用 Spring Boot 进行测试时仅从测试/资源中加载数据
无法在 Spring Boot 测试中加载类 [pg-uuid]
IntelliJ IDEA spring boot 远程Ddbug调试