【问题标题】:@SpyBean not working with Pact and JUnit 5@SpyBean 不适用于 Pact 和 JUnit 5
【发布时间】:2019-04-01 05:18:58
【问题描述】:

我正在尝试使用@SpyBean 模拟@Component 的方法,但不起作用。 @MockBean 有效(跟随example)。我尝试、阅读和研究了很多方法,但都无法奏效。

示例如下:

@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment. DEFINED_PORT)
@ExtendWith(SpringExtension::class)
@Provider("MyMicroService")
@PactFolder("../../../pacts")
internal class ClientContracts {

    @SpyBean
    private lateinit var myService: MyService

    @TestTemplate
    @ExtendWith(PactVerificationInvocationContextProvider::class)
    fun pactVerificationTestTemplate(context: PactVerificationContext) {
        context.verifyInteraction()
    }

    @State("default", "NO_DATA")
    fun toDefaultState() {
        reset(processService)
    }
}

(我超级简化了测试功能,所以它更容易阅读,我实际上是在做doReturn(...).when(...).blah()

我总是收到“not a mock”错误,因为对象始终是 Spring CGLIB 包装的 bean:

org.mockito.exceptions.misusing.NotAMockException: Argument should be a mock, but is: class com.blah.MyServiceImpl$$EnhancerBySpringCGLIB$$9712a2a5
    at com.nhaarman.mockitokotlin2.MockitoKt.reset(Mockito.kt:36)
...

我试过了:

  • @SpringJUnitConfig
  • 使用单独的@TestConfiguration,但解析为与上述 bean 相同
  • @BeforeEach 中使用Mockito.initAnnotations(this)
  • 还有更多,我尝试了很多我不记得的组合...

我有什么遗漏的吗?还是我不知道的选项?

【问题讨论】:

    标签: spring-boot kotlin pact pact-jvm


    【解决方案1】:
    1. 上述问题与 pact 或 pact JVM 库无关
    2. 问题不在于弹簧
      • Spring - 我将 spring 与 mockito 一起使用,它可以工作,简单的例子是:
    import com.nhaarman.mockito_kotlin.doReturn
    import org.junit.jupiter.api.Test
    import org.junit.jupiter.api.extension.ExtendWith
    import org.springframework.boot.test.context.SpringBootTest
    import org.springframework.boot.test.mock.mockito.SpyBean
    import org.springframework.test.context.junit.jupiter.SpringExtension
    
    @ExtendWith(value = [SpringExtension::class])
    @SpringBootTest(
     webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
     classes = [Application::class]
    )
    internal class processorIntegrationTest : IntegrationTest() {
    
     @SpyBean
    //    @MockBean
     private lateinit var processor: Processor;
    
     @Test
     internal fun abcd() {
         doReturn("something").`when`(processor).get()
    
         val get = processor.get()
         assertThat(get).isEqualTo("something")
     }
    }
    
    1. Mockito - mockito_kotlinmockito 扩展适用于 SpyBean

    2. 问题是关于mockito + CGLIB

      • CGLIB - 从您的日志中感觉就像class com.blah.MyServiceImpl$$EnhancerBySpringCGLIB$$9712a2a5 在您的服务实现之上有一个包装器SpyBean。 这意味着 CGLIB 包装器不是,错误是针对此的。 尝试删除 CGLIB 包装器,它会起作用

    【讨论】:

    • 感谢您抽出宝贵时间参与本次 Gopinath。 CGLIB 包装器不是我控制的(仅与 SpyBean 一起出现)。您将如何解开服务或完全避免使用 cglib 包装器?
    • 当然你可以解开 CGLIB 包装器和测试检查这个如何解开 CGLIB stackoverflow.com/questions/9033874/…
    • 成功了。谢谢!不知道有一个测试实用程序。我仍然想知道 MockBean 不需要它。也许是另一天的故事:)
    • 很高兴听到这个消息。
    猜你喜欢
    • 2019-05-12
    • 1970-01-01
    • 1970-01-01
    • 2019-09-07
    • 2019-05-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多