【问题标题】:Test with Spring annotations causes ClosedByInterruptException when executed in maven test run在 Maven 测试运行中执行时,使用 Spring 注释进行测试会导致 ClosedByInterruptException
【发布时间】:2019-10-10 21:08:04
【问题描述】:

我有一个如下所示的测试类:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = TestClass.TestConfig.class)
public class TestClass{

    @Configuration
    @EnableAspectJAutoProxy
    @ComponentScan(basePackages = "package.with.dummy.provider.and.aspect", includeFilters = { 
            @Filter(Aspect.class), @Filter(Provider.class) })
    public static class TestConfig {

        @Bean
        CustomApplicationListener listener() {
            return new CustomApplicationListener ();
        }

    }

    @Autowired
    CustomApplicationListener listener;

    @Test
    public void testMethod() {
        // Do something with the listener
    }    
}

当我使用 Eclipse 中的 JUnit 运行它时,它工作得很好。但是当测试在我的 Maven 构建/测试周期中执行时,它会失败并出现以下异常:

java.lang.IllegalStateException: Failed to load ApplicationContext
     at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:125)
[...]
Caused by: org.springframework.beans.factory.BeanDefinitionStoreException: Failed to read candidate component class: file [Path\To\Aspect\DummyAspect.class]; nested exception is java.nio.channels.ClosedByInterruptException
     at org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider.scanCandidateComponents(ClassPathScanningCandidateComponentProvider.java:454)
[...]
Caused by: java.nio.channels.ClosedByInterruptException
     [java]     at java.nio.channels.spi.AbstractInterruptibleChannel.end(AbstractInterruptibleChannel.java:220)
     [java]     at sun.nio.ch.FileChannelImpl.size(FileChannelImpl.java:327)
     [java]     at sun.nio.ch.ChannelInputStream.available(ChannelInputStream.java:128)
     [java]     at java.io.BufferedInputStream.available(BufferedInputStream.java:421)
     [java]     at org.springframework.asm.ClassReader.readClass(ClassReader.java:479)
     [java]     at org.springframework.asm.ClassReader.<init>(ClassReader.java:445)
     [java]     at org.springframework.core.type.classreading.SimpleMetadataReader.<init>(SimpleMetadataReader.java:54)
     [java]     at org.springframework.core.type.classreading.SimpleMetadataReaderFactory.getMetadataReader(SimpleMetadataReaderFactory.java:103)
     [java]     at org.springframework.core.type.classreading.CachingMetadataReaderFactory.getMetadataReader(CachingMetadataReaderFactory.java:123)
     [java]     at org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider.scanCandidateComponents(ClassPathScanningCandidateComponentProvider.java:430)

我想知道从 Eclipse 与从 maven 执行测试的差异可能导致观察到的情况发生。

更新@ComponentScan 注释中删除 basePackages = "package.with.dummy.provider.and.aspect" 时,一切正常!包路径是正确的。现在,如果有人能解释为什么会发生这种情况......

更新 2 好吧,看起来它甚至更陌生。经过更多测试后,我可以确认测试通过一次,只要我更改basePackages 的值。在我删除了值并且测试通过的第一次更新之后,它在文本时间和之后的每次都失败了。然后我尝试将值更改为package.with.dummy.provider.and,删除一个级别,它通过了 - 一次。听起来maven在构建和测试过程中生成的某些文件可能没有正确清理,因此@ComponentScan会多次查找并尝试读取这些文件,这会导致ClosedByInterruptException

【问题讨论】:

  • 您的 Eclipse 中是否安装了 Spring Tool Suite(3 或 4)? Eclipse中的JUnit通常意味着STS支持的循环。
  • 检查之前的一些测试是否调用了Thread.currentThread().interrupt()

标签: java spring maven unit-testing junit


【解决方案1】:

我遇到了同样的问题,解决方法如下。

现在 spock 框架支持 JUnit 5,现在您可以使用 JUnit 5 运行 spock 测试用例了。

将您的 spock 升级到最新版本 [2.0-M1-groovy-2.5(尚未发布,但我们现在可以使用解决方案)]

并将以下新依赖项添加到您的项目中。

testCompile group: 'org.junit.platform', name: 'junit-platform-engine', version: '1.5.2'
compile group: 'org.junit.platform', name: 'junit-platform-commons', version: '1.5.2'

现在运行gradle test 任务,它将同时运行 spock 和 JUnit5 测试用例而不会失败。

快乐编码... :)

【讨论】:

    猜你喜欢
    • 2019-12-06
    • 2018-08-23
    • 1970-01-01
    • 1970-01-01
    • 2011-06-06
    • 2016-12-02
    • 1970-01-01
    • 2012-06-19
    • 2012-04-23
    相关资源
    最近更新 更多