首页 > 解决方案 > Kotlin:如何使用 JUnit5 和 Mockk 清理或重置模拟

问题描述

在某些情况下,需要清理或重置测试用例之间的模拟。

将 Kotling 与 JUnit5 和 Mockk 一起使用,第一种方法应该是这样的:

class CreateProductsTests {

    @Test
    fun `run() with an existing product should throw a CrudException`() {

        val productRepository = mockk<ProductRepository>()
        val editorService = mockk<EditorService>()
        val sut = CreateProductServiceImpl(productRepository, editorService)

        // Given an editor that return a JSON
        val product = completeTestProduct()
        every { editorService.edit("Create new Product", product) } returns product

        // And the product does exist in the database
        every { productRepository.findById(product.id) } returns Optional.of(product)

        // When we call createProduct()"
        // Then should fail
        val exception = assertFailsWith<CrudException> { sut.createProduct() }
        exception.message shouldBe "The product 'TST' already exists in database"
    }

    @Test
    fun `createProduct() with an invalid product should fail`() {

        val productRepository = mockk<ProductRepository>()
        val editorService = mockk<EditorService>()
        val sut = CreateProductServiceImpl(productRepository, editorService)

        // Given an editor that return a JSON
        val product = completeTestProduct()
        every { editorService.edit("Create new Product", product) } returns product

        // And the product does exist in the database
        every { productRepository.findById(product.id) } returns Optional.of(product)

        // And a repository saves the product
        every { productRepository.save(product) } returns product

        // When we call createProduct()"
        val actual = sut.createProduct()

        // Then it should return the product
        actual shouldBe product

        // And should call once these dependencies
        verify(exactly = 1) {
            editorService.edit(any<String>(), any<Product>())
            productRepository.findById(any<String>())
            productRepository.save(any<Product>())
        }
    }
}

@BeforeEach但是,与其在每个测试用例上声明模拟并初始化 SUT,不如使用类似这样的东西更清晰(可能不是更快) :

class CreateProductsTests {

    var productRepository = mockk<ProductRepository>()
    var editorService = mockk<EditorService>()
    var sut = CreateProductServiceImpl(productRepository, editorService)

    @BeforeEach
    fun clear() {
        productRepository = mockk<ProductRepository>()
        editorService = mockk<EditorService>()
        sut = CreateProductServiceImpl(productRepository, editorService)
    }
...

有没有更好(和更快)的方法来声明模拟和 sut 一次并在每次测试中重置或清除所有模拟?

标签: kotlinjunit5mockk

解决方案


你应该试试:

 @AfterEach
internal fun tearDown() {
    clearAllMocks()
}

推荐阅读