带有 SpringRunner.class 的 JUnit @Category 注释

JUnit @Category annotation with SpringRunner.class

我按照 this blog post 使用 @Category 注释设置了带有单独单元和集成测试的 Maven 构建。

在大多数情况下这是有效的:标记为 @Category(IntegrationTest.class) 的测试在 integration-test 阶段执行,所有未标记的测试在 test 阶段执行。

但是,当单元测试 运行 时,集成测试的上下文似乎仍在(部分?)创建,即使测试本身不是 运行:

[INFO] --- maven-surefire-plugin:2.18.1:test (default-test) @ bamboo ---
[INFO] Surefire report directory: [removed]
[INFO] Using configured provider org.apache.maven.surefire.junitcore.JUnitCoreProvider
[INFO] parallel='none', perCoreThreadCount=true, threadCount=0, useUnlimitedThreads=false, threadCountSuites=0, threadCountClasses=0, threadCountMethods=0, parallelOptimized=true

-------------------------------------------------------
 T E S T S
-------------------------------------------------------
09:56:05.458 [main] DEBUG org.springframework.test.context.junit4.SpringJUnit4ClassRunner - SpringJUnit4ClassRunner constructor called with [class com.example.MyIntegrationTest]
09:56:05.463 [main] DEBUG org.springframework.test.context.BootstrapUtils - Instantiating CacheAwareContextLoaderDelegate from class [org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate]
09:56:05.468 [main] DEBUG org.springframework.test.context.BootstrapUtils - Instantiating BootstrapContext using constructor [public org.springframework.test.context.support.DefaultBootstrapContext(java.lang.Class,org.springframework.test.context.CacheAwareContextLoaderDelegate)]
09:56:05.481 [main] DEBUG org.springframework.test.context.BootstrapUtils - Instantiating TestContextBootstrapper for test class [com.example.MyIntegrationTest] from class [org.springframework.boot.test.context.SpringBootTestContextBootstrapper]
09:56:05.494 [main] INFO org.springframework.boot.test.context.SpringBootTestContextBootstrapper - Neither @ContextConfiguration nor @ContextHierarchy found for test class [com.example.MyIntegrationTest], using SpringBootContextLoader
09:56:05.497 [main] DEBUG org.springframework.test.context.support.AbstractContextLoader - Did not detect default resource location for test class [com.example.MyIntegrationTest]: class path resource [com/example/MyIntegrationTest-context.xml] does not exist
09:56:05.497 [main] DEBUG org.springframework.test.context.support.AbstractContextLoader - Did not detect default resource location for test class [com.example.MyIntegrationTest]: class path resource [com/example/MyIntegrationTestContext.groovy] does not exist
09:56:05.497 [main] INFO org.springframework.test.context.support.AbstractContextLoader - Could not detect default resource locations for test class [com.example.MyIntegrationTest]: no resource found for suffixes {-context.xml, Context.groovy}.
09:56:05.530 [main] DEBUG org.springframework.test.context.support.ActiveProfilesUtils - Could not find an 'annotation declaring class' for annotation type [org.springframework.test.context.ActiveProfiles] and class [com.example.MyIntegrationTest]
09:56:05.563 [main] DEBUG org.springframework.boot.test.context.SpringBootTestContextBootstrapper - @TestExecutionListeners is not present for class [com.example.MyIntegrationTest]: using defaults.
09:56:05.567 [main] INFO org.springframework.boot.test.context.SpringBootTestContextBootstrapper - Loaded default TestExecutionListener class names from location [META-INF/spring.factories]: [org.springframework.boot.test.mock.mockito.MockitoTestExecutionListener, org.springframework.boot.test.mock.mockito.ResetMocksTestExecutionListener, org.springframework.boot.test.autoconfigure.restdocs.RestDocsTestExecutionListener, org.springframework.boot.test.autoconfigure.web.client.MockRestServiceServerResetTestExecutionListener, org.springframework.boot.test.autoconfigure.web.servlet.MockMvcPrintOnlyOnFailureTestExecutionListener, org.springframework.boot.test.autoconfigure.web.servlet.WebDriverTestExecutionListener, org.springframework.test.context.web.ServletTestExecutionListener, org.springframework.test.context.support.DirtiesContextBeforeModesTestExecutionListener, org.springframework.test.context.support.DependencyInjectionTestExecutionListener, org.springframework.test.context.support.DirtiesContextTestExecutionListener, org.springframework.test.context.transaction.TransactionalTestExecutionListener, org.springframework.test.context.jdbc.SqlScriptsTestExecutionListener]
09:56:05.580 [main] INFO org.springframework.boot.test.context.SpringBootTestContextBootstrapper - Could not instantiate TestExecutionListener [org.springframework.test.context.web.ServletTestExecutionListener]. Specify custom listener classes or make the default listener classes (and their required dependencies) available. Offending class: [javax/servlet/ServletContext]
09:56:05.586 [main] INFO org.springframework.boot.test.context.SpringBootTestContextBootstrapper - Using TestExecutionListeners: [org.springframework.test.context.support.DirtiesContextBeforeModesTestExecutionListener@62fdb4a6, org.springframework.boot.test.autoconfigure.SpringBootDependencyInjectionTestExecutionListener@11e21d0e, org.springframework.test.context.support.DirtiesContextTestExecutionListener@1dd02175, org.springframework.test.context.transaction.TransactionalTestExecutionListener@31206beb, org.springframework.test.context.jdbc.SqlScriptsTestExecutionListener@3e77a1ed, org.springframework.boot.test.autoconfigure.web.client.MockRestServiceServerResetTestExecutionListener@3ffcd140, org.springframework.boot.test.mock.mockito.MockitoTestExecutionListener@23bb8443, org.springframework.boot.test.mock.mockito.ResetMocksTestExecutionListener@1176dcec, org.springframework.boot.test.autoconfigure.restdocs.RestDocsTestExecutionListener@120d6fe6, org.springframework.boot.test.autoconfigure.web.servlet.MockMvcPrintOnlyOnFailureTestExecutionListener@4ba2ca36, org.springframework.boot.test.autoconfigure.web.servlet.WebDriverTestExecutionListener@3444d69d]
09:56:05.591 [main] DEBUG org.springframework.test.annotation.ProfileValueUtils - Retrieved @ProfileValueSourceConfiguration [null] for test class [com.example.MyIntegrationTest]
09:56:05.591 [main] DEBUG org.springframework.test.annotation.ProfileValueUtils - Retrieved ProfileValueSource type [class org.springframework.test.annotation.SystemProfileValueSource] for class [com.example.MyIntegrationTest]
Running com.example.MyUnitTest
Tests run: 2, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.323 sec - in com.example.MyUnitTest

MyIntegrationTest是这样注释的:

@Category(IntegrationTest.class)
@RunWith(SpringRunner.class)
@SpringBootTest(classes = TestApp.class)
public class MyIntegrationTest {
    @Autowired
    private ActualObject actualObject;
}

如何防止这种行为?

这会创建一个 TestContext,但不会对其进行初始化,因此速度应该很快。

对于每个测试 class,都会创建一个 Spring TestContextManager,如 SpringJUnit4ClassRunner.java 的构造函数中所定义(与 SpringRunner.java 相同)。

我认为除了实际排除测试文件本身之外,您无法避免创建 TestRunner。

您可以通过在 test/resources 文件夹中添加 logback-test.xml 来最好地抑制这些日志。

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <include resource="org/springframework/boot/logging/logback/base.xml" />
    <logger name="org.springframework" level="ERROR"/>
</configuration>