在Maven测试运行中执行时,使用Spring批注进行测试会导致ClosedByInterruptException

时间:2019-05-24 09:28:06

标签: spring maven unit-testing junit

我有一个看起来像这样的测试类:

@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执行测试的不同之处,这可能导致观察到的情况发生。

更新basePackages = "package.with.dummy.provider.and.aspect"批注中删除@ComponentScan时,一切都会按预期进行!包路径是正确的。现在,如果有人可以解释为什么会这样...

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

1 个答案:

答案 0 :(得分:0)

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

现在,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测试用例而不会失败。

快乐编码... :)