问题
I want to inject DeMorgenArticleScraper in a test.
@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.
@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. The class itself has @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. But as far as I know, it is defined in a bean with the @Component annotation. All other bean wiring seems ok as the Spring boot application can start (when I comment out the test class).
回答1:
@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. Depending on what you are trying to test you may want to look into
- Slice tests e.g.
@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. Benefit of these tests are not only will they not load everything, thus faster, but will try to hunt out the relevant configurations. - Plain old
@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
回答2:
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. I'll keep this question open for a short while for better suggestions.
回答3:
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.@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.
@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.
Also, as alternative to @SpringBootTest
with classes={..}
, you can uncomment line with @ContextConfiguration
. It is plain old style.
来源:https://stackoverflow.com/questions/44787722/spring-boot-field-injection-with-autowire-not-working-in-junit-test