【问题标题】:how to make mockito test case with Constructor injection如何使用构造函数注入制作模拟测试用例
【发布时间】:2020-03-29 16:23:39
【问题描述】:

我想用 mockito 制作 junit 测试用例

有课程。

MyProps : the properties data class @Configuration
MyService : my main logic @Service class
MyClient : webClient class @Component

如何使用 mockito 测试 myService 结果逻辑?以及如何简单地制作数据类(MyProps)???

有错误是这样的: 您没有在字段声明时提供实例,所以我尝试构建实例。 但是构造函数或初始化块抛出异常:指定为非空的参数为空:

@Configuration
@ConfigurationProperties("application.something")
class MyProps {
    lateinit var broker: String
    lateinit var url: String
}

@Service
class MyService(private val client: MyClient,
                private val myProps: MyProps
){

    fun getReulst(params: Params): Flux<MyEntity> {

        // some logic, and I want check this part result

        return client.get(params)
    }
}

@Component
class MyClient(val myProps: MyProps) {

    private val webClient: WebClient = WebClient.create()

    fun get(params: Params): Flux<MyEntity> {

        val params = BodyInserters.fromValue(query)

        return webClient
                .post()
                .uri(myProps.broker)
                .contentType(MediaType.APPLICATION_JSON)
                .accept(MediaType.APPLICATION_JSON)
                .body(params)
                .retrieve()
                .bodyToFlux(MyEntity::class.java)
    }
}

这里是测试代码


//----------------

@SpringBootTest(classes = [MyService::class, MyProps::class, MyClient::class])
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class MyServiceTest {

    @MockBean
    private lateinit var myProps: MyProps

    @MockBean
    private lateinit var myClient: MyClient

    @InjectMocks
    private lateinit var countService: MyService


    @BeforeEach
    fun mock() {
        given(myProps.broker).willReturn("http://url.com")
        given(myProps.web).willReturn("something")

        given(myClient.get2(query)).willReturn(
                Flux.fromIterable(listOf(
                        MyEntity("2020-03-22", Count(1)),
                        MyEntity("2020-03-23", Count(2)),
                        MyEntity("2020-03-24", Count(3)),
                        MyEntity("2020-03-25", Count(6)),
                        MyEntity("2020-03-26", Count(5)),
                        MyEntity("2020-03-27", Count(4))
                ))
        )

        MockitoAnnotations.initMocks(this)
    }

    @Test
    fun `I want to check!! here`(){
            val param = Params(1,2,3) // some params

            myService.getReulst(param).subscribe() // <-  here is error maybe param is null... why??
    }
}

【问题讨论】:

  • 看起来可疑的第一件事是 @BeforeEach 末尾的 MockitoAnnotations.initMocks(this)

标签: kotlin junit mockito


【解决方案1】:

由于您将模拟注入到您的服务中,因此您实际上并不需要完整的 Spring Boot 测试。这将使您的测试更快。

此外,既然你在嘲笑MyClient,你并没有真正调用它的代码。因此,MyClient 中发生的任何事情都可以在这里忽略。您将在它自己的测试中介绍它。

以下是我使用 JUnit 5 编写此测试的方式(如果您仍在使用它,则必须将其转换为 JUnit 4):

@ExtendWith(MockitoExtension::class)
class MyServiceTest(
    @Mock val myProps: MyProps,
    @Mock val myClient: MyClient
) {
    // you can use @InjectMocks if you prefer
    val countService: MyService = MyService(myProps, myClient)

    @BeforeEach
    fun mock() {
       // you only need these if they're called in MyService
       `when`(myProps.broker).thenReturn("http://url.com")
       `when`(myProps.web).thenReturn("something")

        `when`(myClient.get(Params(1,2,3))).thenReturn(
            Flux.fromIterable(listOf(
                    MyEntity("2020-03-22", Count(1)),
                    MyEntity("2020-03-23", Count(2)),
                    MyEntity("2020-03-24", Count(3)),
                    MyEntity("2020-03-25", Count(6)),
                    MyEntity("2020-03-26", Count(5)),
                    MyEntity("2020-03-27", Count(4))
            ))
        )
    }

    @Test
    fun `I want to check!! here`(){
        val param = Params(1,2,3)

        myService.getReulst(param).subscribe()
    }
}

【讨论】:

    猜你喜欢
    • 2017-01-29
    • 2018-11-02
    • 1970-01-01
    • 1970-01-01
    • 2015-05-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-19
    相关资源
    最近更新 更多