Kotlin: как убрать или сбросить макеты с помощью JUnit5 и Mockk - PullRequest
0 голосов
/ 27 апреля 2019

В некоторых случаях необходимо очистить или сбросить макеты между тестами.

Используя 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>())
        }
    }
}

Но вместо того, чтобы объявлять макеты в каждом тестовом примере и инициализировать SUT, возможно, это будет более понятным (возможно, не быстрее) использовать @BeforeEach, с чем-то вроде этого:

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 один раз и сбросить или очистить все из нихна каждом тесте?

Ответы [ 2 ]

2 голосов
/ 28 апреля 2019

Вы должны попробовать это:

 @AfterEach
internal fun tearDown() {
    clearAllMocks()
}
1 голос
/ 17 мая 2019

Вы можете инициализировать макеты и подавать один раз и сбрасывать макеты перед каждым тестом, но вам нужно порождать только один раз экземпляр вашего тестового класса.Вот как это будет выглядеть:

@TestInstance(Lifecycle.PER_CLASS)
class CreateProductsTests {

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

    @BeforeAll
    fun setup() {
        MockKAnnotations.init(this)
        sut = CreateProductServiceImpl(productRepository, editorService)
    }

    @BeforeEach
    fun clear() {
        clearMocks(productRepository, editorService)
    }
...
...