[英]Spring boot field injection with autowire not working in JUnit test
我想在测试中注入 DeMorgenArticleScraper。
@RunWith(SpringJUnit4ClassRunner.class)
public class DeMorgenArticleScraperTest {
@Autowired
private DeMorgenArticleScraper deMorgenArticleScraper;
...
}
DeMorgenArticleScraper 组件自己进行了一些配置,但 IDE/编译器并没有抱怨它们。
@Component
public class DeMorgenArticleScraper extends NewsPaperArticleScraper {
@Autowired
public DeMorgenArticleScraper(
@Qualifier("deMorgenSelectorContainer") SelectorContainer selector,
GenericArticleScraper genericArticleScraper,
@Qualifier("deMorgenCompany") Company company) {
super(selector, genericArticleScraper, company);
}
...
}
使用@Qualifier 注释的构造函数参数在带有@Bean 的Config.class 中定义。 class 本身具有@Configuration。 我认为问题不在这里。
IDE 已经警告我,没有找到 bean...自动装配的成员必须在 bean 中定义。 但据我所知,它是在带有 @Component 注释的 bean 中定义的。 所有其他 bean 接线似乎都可以,因为 Spring 引导应用程序可以启动(当我注释掉测试类时)。
我换了
@RunWith(SpringJUnit4ClassRunner.class)
和
@SpringBootTest
@RunWith(SpringRunner.class)
这似乎工作正常:我看到 Spring Boot 启动并加载 bean。 我会暂时保留这个问题以获得更好的建议。
@SpringBootTest
是相当重量级的,并且出于所有意图和目的将加载您的整个应用程序, https: @SpringBootTest
features-testing-spring-boot-applications ,它是相当重量级的并且极大地影响了测试时间。 根据您要测试的内容,您可能需要查看
@JsonTest
、 @DataJpaTest
、 @WebMvcTest
等, https : @JsonTest
spring-boot-applications-testing-autoconfigured-tests 。 这些测试的好处不仅在于它们不会加载所有内容,因此速度更快,而且会尝试找出相关配置。@ContextConfiguration
并指向加载测试所需的 bean 所需的相关@Configuration
https://docs.spring.io/spring/docs/current/spring-framework-reference/testing.html#contextconfiguration我遇到了类似的问题,我的 spring 上下文没有被初始化,因此我无法用@Autowired
注释注入 bean。 然后我遇到了这篇文章,并按照@progonkpa 的建议尝试了以下注释,它开始工作。
@SpringBootTest
@RunWith(SpringRunner.class)
但后来我意识到@SpringBootTest
已经包含@ExtendWith({SpringExtension.class})
注释,它是 Junit5 等效于@RunWith(SpringRunner.class)
因此它应该在运行测试时加载 spring-context。 然后我发现了从 junit4(即org.junit.Test;
)而不是 junit5(即org.junit.jupiter.api.Test;
)库导入@Test
注释时犯的愚蠢错误。 我更改了 junit5 库中的@Test
,它开始使用单个注释@SpringBootTest
。
ps:如果您使用的是junit5,请不要忘记从您的依赖项中排除junit4库
我有同样的问题。
有一个服务,我想注入它进行测试,但我只想测试platformToSql(..)
方法而不启动整个 Spring Boot 应用程序。
@Service public class ConverterToSqlImpl implements IConverterToSql { private final ISomeRepository someRepository; private final IUtilService utilService; public ConverterToSqlMainConstructorServiceImpl( IWorkerUtilService workerUtilService, ISomeRepository someRepository) { this.utilService = utilService; this.someRepository = someRepository; } @Override public String platformToSql(String platformName) { return "platform='" + platformName + "'"; } @Override public String methodWhichUseRepositoryAndUtilBeans() { // some code which is not interested us } }
我创建测试类。 模拟 bean 是必要的,因为它们不需要测试方法。
@RunWith(SpringRunner.class) @SpringBootTest(classes = {ConverterToSqlImpl.class}) //@ContextConfiguration(classes = {ConverterToSqlImpl.class}) @MockBeans({@MockBean(IUtilService.class), @MockBean(ISomeRepository.class)}) public class SqlConverterConstructorTest { @Autowired private IConverterToSqlMainConstructorService convertToSql; @Test public void platformTest() { String platformSql = convertToSql.platformToSql("PLATFORM_1"); String expectedSql = "platform='PLATFORM_1'"; Assert.assertEquals(platformSql, expectedSql); } }
@SpringBootTest(classess = {})
仅将在classess
部分指出的 classess 加载到ApplicationContext
,不会启动包含所有 bean 的整个应用程序。
此外,作为使用classes={..}
替代@SpringBootTest
,您可以使用@ContextConfiguration
取消注释行。 这是朴素的旧风格。
使用 Junit5 对我有用,然后只需 @SpringBootTest 和 @ActiveProfiles ("test") 注释就足够了。 当然,我必须在 /test/resources 路径中有一个 application-test.properties。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.