NotAMockException / Как заглушить значение в параметризованном тесте в Kotlin? - PullRequest
0 голосов
/ 04 декабря 2018

Для следующего класса Kotlin:

class ProductLogic(

        private val product: Product?

) {

    fun shouldShow(): Boolean {
        if (product == null) {
            return false
        }
        val version = product.version!!
        if (!Utils.isAtLeastVersionX(version.major, version.minor)) {
            return false
        }
        return true
    }

}

Я пытаюсь написать параметризованный тест в Kotlin:

@RunWith(ParameterizedRobolectricTestRunner::class)
@Config(constants = BuildConfig::class, sdk = [19], packageName = "com.example")
class ProductLogicTest(

        private val product: Product?,
        private val shouldShow: Boolean

) {

    @Before
    fun setUp() {
        // doReturn(VERSION).`when`(product).version // (2) Raises a NotAMockException
    }

    @Test
    fun shouldShow() {
        assertThat(ProductLogic(product).shouldShow(), `is`(shouldShow))
    }

    companion object {
        @JvmStatic
        @Parameters(name = "{index}: {0} => {1}")
        fun data(): Collection<Array<Any?>> {
            val productMock = mock<Product>(Product::class.java)
            doReturn(VERSION).`when`(productMock).version // (1) Is not applied
            return asList(
                       arrayOf(productMock, false),
                       // ...
            )
        }

}

Я хочу параметризовать значение свойства Product#version,Когда я (1) изменяю его значение в функции data(), оно не применяется при выполнении теста.Когда я (2) пытаюсь изменить его значение в @Before, значение NotAMockException увеличивается:

org.mockito.exceptions.misusing.NotAMockException: 
Argument passed to when() is not a mock!
Example of correct stubbing:
    doThrow(new RuntimeException()).when(mock).someMethod();

Обратите внимание, что пример упрощен - настоящий класс ProductLogic состоит из болеепараметры, которые исправляются с помощью параметризованного теста.

1 Ответ

0 голосов
/ 14 декабря 2018

Robolectric и Mockito версии:

testImplementation 'org.robolectric:robolectric:4.1'
testImplementation 'org.mockito:mockito-core:2.23.4'

Также, чтобы высмеивать финальные классы, я создал файл src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker с содержанием:

mock-maker-inline

Классы для тестирования:

class ProductLogic(private val product: Product?) {
    fun shouldShow(): Boolean {
        if (product == null) {
            return false
        }
        val version = product.version
        return !isAtLeastVersionX(version.minor, version.major)
    }

    private fun isAtLeastVersionX(minor: Int, major: Int): Boolean {
        val v = 5
        return v in minor..major
    }
}

class Product(val version: Version)

class Version(val minor: Int, val major: Int)

У меня работает следующий тестовый код и тест пройден:

import org.hamcrest.CoreMatchers.`is`
import org.junit.Assert.assertThat
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.Mockito.doReturn
import org.mockito.Mockito.mock
import org.robolectric.ParameterizedRobolectricTestRunner
import org.robolectric.annotation.Config
import java.util.Arrays.asList

@RunWith(ParameterizedRobolectricTestRunner::class)
@Config(sdk = [19], packageName = "com.example")
class ProductLogicTest(private val product: Product,
                       private val shouldShow: Boolean) {

    @Before
    fun setUp() {
        //doReturn(VERSION).`when`(product).version // if uncomment works fine
    }

    @Test
    fun shouldShow() {
        assertThat(ProductLogic(product).shouldShow(), `is`(shouldShow))
    }


    companion object {
        private val VERSION = Version(1, 5)

        @JvmStatic
        @ParameterizedRobolectricTestRunner.Parameters(name = "{index}: {0} => {1}")
        fun data(): Collection<Array<Any?>> {
            val productMock = mock(Product::class.java)
            doReturn(VERSION).`when`(productMock).version // Works fine
            return asList(
                    arrayOf(productMock, false)
            )
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...