[英]Spring boot field injection with autowire not working in JUnit test
I want to inject DeMorgenArticleScraper in a test.我想在测试中注入 DeMorgenArticleScraper。
@RunWith(SpringJUnit4ClassRunner.class)
public class DeMorgenArticleScraperTest {
@Autowired
private DeMorgenArticleScraper deMorgenArticleScraper;
...
}
The DeMorgenArticleScraper component has some configuration going on for itself, but the IDE/compiler is not complaining about them. 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);
}
...
}
The constructor parameters that are annotated with @Qualifier, are defined in a Config.class With @Bean.使用@Qualifier 注释的构造函数参数在带有@Bean 的Config.class 中定义。 The class itself has @Configuration.
class 本身具有@Configuration。 I figure the problem is not situated here.
我认为问题不在这里。
The IDE warns me already, no bean found...autowired members must be defined in a bean. IDE 已经警告我,没有找到 bean...自动装配的成员必须在 bean 中定义。 But as far as I know, it is defined in a bean with the @Component annotation.
但据我所知,它是在带有 @Component 注释的 bean 中定义的。 All other bean wiring seems ok as the Spring boot application can start (when I comment out the test class).
所有其他 bean 接线似乎都可以,因为 Spring 引导应用程序可以启动(当我注释掉测试类时)。
I replaced我换了
@RunWith(SpringJUnit4ClassRunner.class)
with和
@SpringBootTest
@RunWith(SpringRunner.class)
This appears to be working fine: I see Spring boot firing up and loading beans.这似乎工作正常:我看到 Spring Boot 启动并加载 bean。 I'll keep this question open for a short while for better suggestions.
我会暂时保留这个问题以获得更好的建议。
@SpringBootTest
is fairly heavyweight, and for all intents and purpose will load your entire application, https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-testing.html#boot-features-testing-spring-boot-applications , it's fairly heavyweight and dramatically affects test time. @SpringBootTest
是相当重量级的,并且出于所有意图和目的将加载您的整个应用程序, https: @SpringBootTest
features-testing-spring-boot-applications ,它是相当重量级的并且极大地影响了测试时间。 Depending on what you are trying to test you may want to look into根据您要测试的内容,您可能需要查看
@JsonTest
, @DataJpaTest
, @WebMvcTest
etc. , https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-testing.html#boot-features-testing-spring-boot-applications-testing-autoconfigured-tests .@JsonTest
、 @DataJpaTest
、 @WebMvcTest
等, https : @JsonTest
spring-boot-applications-testing-autoconfigured-tests 。 Benefit of these tests are not only will they not load everything, thus faster, but will try to hunt out the relevant configurations.@ContextConfiguration
and point to the relevant @Configuration
's required to load beans needed for the test https://docs.spring.io/spring/docs/current/spring-framework-reference/testing.html#contextconfiguration@ContextConfiguration
并指向加载测试所需的 bean 所需的相关@Configuration
https://docs.spring.io/spring/docs/current/spring-framework-reference/testing.html#contextconfigurationI ran into similar problem where my spring context was not getting initialized and therefore I was not able to inject the bean with @Autowired
annotation.我遇到了类似的问题,我的 spring 上下文没有被初始化,因此我无法用
@Autowired
注释注入 bean。 Then I came across this post and tried with the below annotations as suggested by @progonkpa and it started working.然后我遇到了这篇文章,并按照@progonkpa 的建议尝试了以下注释,它开始工作。
@SpringBootTest
@RunWith(SpringRunner.class)
But then I realized that @SpringBootTest
already contains @ExtendWith({SpringExtension.class})
annotation which is Junit5 equivalent of @RunWith(SpringRunner.class)
thus it should load spring-context while running the test.但后来我意识到
@SpringBootTest
已经包含@ExtendWith({SpringExtension.class})
注释,它是 Junit5 等效于@RunWith(SpringRunner.class)
因此它应该在运行测试时加载 spring-context。 Then I found out the silly mistake I made to import @Test
annotation from junit4(ie org.junit.Test;
) instead of junit5(ie org.junit.jupiter.api.Test;
) library.然后我发现了从 junit4(即
org.junit.Test;
)而不是 junit5(即org.junit.jupiter.api.Test;
)库导入@Test
注释时犯的愚蠢错误。 I changed the @Test
from junit5 library and it started working with a single annotation @SpringBootTest
.我更改了 junit5 库中的
@Test
,它开始使用单个注释@SpringBootTest
。
ps : don't forget to exclude junit4 library from your dependency if you are using junit5 ps:如果您使用的是junit5,请不要忘记从您的依赖项中排除junit4库
I have the same problem.我有同样的问题。
There is service, which I want to inject for testing but I want to test only platformToSql(..)
method without launching whole Spring Boot application.有一个服务,我想注入它进行测试,但我只想测试
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 } }
I create test class.我创建测试类。 It is necessary to mock beans because they are not need for test method.
模拟 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 = {})
load to ApplicationContext
only classess which are pointed out in classess
section, not whole application with all beans will be lauched. @SpringBootTest(classess = {})
仅将在classess
部分指出的 classess 加载到ApplicationContext
,不会启动包含所有 bean 的整个应用程序。
Also, as alternative to @SpringBootTest
with classes={..}
, you can uncomment line with @ContextConfiguration
.此外,作为使用
classes={..}
替代@SpringBootTest
,您可以使用@ContextConfiguration
取消注释行。 It is plain old style.这是朴素的旧风格。
Using Junit5 worked for me and then just the @SpringBootTest and @ActiveProfiles ("test") annotation was sufficient.使用 Junit5 对我有用,然后只需 @SpringBootTest 和 @ActiveProfiles ("test") 注释就足够了。 Of course, I had to have an application-test.properties in the /test/resources path.
当然,我必须在 /test/resources 路径中有一个 application-test.properties。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.