使用Mockito用@Transactional方法模拟一个类

问题描述 投票:1回答:1

我有一个服务,一个bean,包含一个@Transactional方法:

public class InMessageService {

...

    @Transactional

    public boolean retryInMessage(String messageId) {

    ...

    }

}

为了测试,我尝试使用Mockito模拟该服务:

@Bean
@Primary
public InMessageService inMessageService() {
    return Mockito.mock(InMessageService.class);
}

当我开始测试时,结果如下:

   Caused by: org.springframework.aop.framework.AopConfigException: Could not generate CGLIB
subclass of class somePackage.InMessageService$MockitoMock$156222813: Common
causes of this problem include using a final class or a non-visible class;nested exception is
org.springframework.cglib.core.CodeGenerationException: java.lang.NoClassDefFoundError-->
somePath/InMessageService$MockitoMock$156222813

我想提一下,相同的代码正在使用spring-boot 1.2.1和Mockito 1.10.19。我尝试使用spring boot 2.1.1和Mockito 2.23.0运行上面的代码

我到目前为止的观察:

  • 无论我使用的2.1.0和2.23.0之间的Mockito版本,异常都是一样的。我不能(也不想)使用旧版本的Mockito,因为项目不再编译
  • 如果我临时删除@Transactional注释,则不会抛出异常。

有什么想法需要通过弹簧启动升级来调整,以便测试再次工作?

谢谢 !

spring-boot junit mockito cglib
1个回答
1
投票

从版本2.1.0开始,Mockito保留了代理方法的注释。这意味着Spring会尝试代理声明事务注释的模拟类,但这会失败,因为模拟方法是最终的。

之前,Mockito剥离了这些注释,这会导致任何真正的方法调用因缺少事务而失败。

为避免这种情况,您需要删除模拟的注释。你可以使用MockSettings.withoutAnnotations这样做。

© www.soinside.com 2019 - 2024. All rights reserved.