Mockito when子句在Kotlin中不起作用

时间:2019-01-08 08:36:21

标签: kotlin mockito

我正在尝试在Kotlin中使用Mockito。我创建了以下测试:

class HeroesDataSourceTest {

    @Mock
    lateinit var heroesRepository: HeroesRepository
    @Mock
    lateinit var params: PageKeyedDataSource.LoadInitialParams<Int>
    @Mock
    lateinit var callback: PageKeyedDataSource.LoadInitialCallback<Int, Heroes.Hero>

    val hero = Heroes.Hero(1, "superman", "holasuperman", 1, null, null)
    val results = Arrays.asList(hero)
    val data = Heroes.Data(results)
    val dataResult = Heroes.DataResult(data)

    val compositeDisposable = CompositeDisposable()

    lateinit var heroesDataSource: HeroesDataSource
    private val heroesPublishSubject = PublishSubject.create<Heroes.DataResult>()

    @Before
    fun initTest(){
        MockitoAnnotations.initMocks(this)

    }

    @Test
    fun testLoadInitialSuccess(){
        `when`(heroesRepository.getHeroes(ArgumentMatchers.anyInt())).thenReturn(heroesPublishSubject.singleOrError())
        heroesDataSource = HeroesDataSource(heroesRepository, compositeDisposable)
        val testObserver = TestObserver<Heroes.DataResult>()
        heroesDataSource.loadInitial(params, callback)
        heroesPublishSubject.onNext(dataResult)
        testObserver.assertComplete()
    }

}

但是当我在when(heroesRepository.getHeroes(ArgumentMatchers.anyInt())).thenReturn(heroesPublishSubject.singleOrError())行中执行它时,它只是进入getHeroes方法而不是对其进行模拟(并且可以肯定的是,由于heroesRepository未初始化,因为它是模拟方法,所以该方法失败了)。我在Java中使用了无数次,但从未给我一个问题。我必须在Kotlin中做些什么才能正确模拟它?

编辑

在这里我还放置了HeroesRepository类

open class HeroesRepository {

    val privateKey = "5009bb73066f50f127907511e70f691cd3f2bb2c"
    val publicKey = "51ef4d355f513641b490a80d32503852"
    val apiDataSource = DataModule.create()
    val pageSize = 20

    fun getHeroes(page: Int): Single<Heroes.DataResult> {
        val now = Date().time.toString()
        val hash = generateHash(now + privateKey + publicKey)
        val offset: Int = page * pageSize
        return apiDataSource.getHeroes(now, publicKey, hash, offset, pageSize)
    }

    fun generateHash(variable: String): String {
        val md = MessageDigest.getInstance("MD5")
        val digested = md.digest(variable.toByteArray())
        return digested.joinToString("") {
            String.format("%02x", it)
        }
    }
}

3 个答案:

答案 0 :(得分:0)

Mockito与Kotlin不太兼容,您可以改为使用Mockito-kotlin资源。 查看此参考: https://github.com/nhaarman/mockito-kotlin

您可以像这样轻松地模拟对象:

from PIL import Image
import sys
import os


def rgb_to_hsv(r, g, b):
    maxc = max(r, g, b)
    minc = min(r, g, b)
    v = maxc
    if minc == maxc:
        return 0.0, 0.0, v
    s = (maxc-minc) / maxc
    rc = (maxc-r) / (maxc-minc)
    gc = (maxc-g) / (maxc-minc)
    bc = (maxc-b) / (maxc-minc)
    if r == maxc:
        h = bc-gc
    elif g == maxc:
        h = 2.0+rc-bc
    else:
        h = 4.0+gc-rc
    h = (h/6.0) % 1.0
    return h, s, v


GREEN_RANGE_MIN_HSV = (100, 80, 70)
GREEN_RANGE_MAX_HSV = (185, 255, 255)

def remove_green_background():
    # Load image and convert it to RGBA, so it contains alpha channel
    name, ext = os.path.splitext(Filepath)
    im = Image.open(Filepath)
    im = im.convert('RGBA')

    # Go through all pixels and turn each 'green' pixel to transparent
    pix = im.load()
    width, height = im.size
    for x in range(width):
        for y in range(height):
            r, g, b, a = pix[x, y]
            h_ratio, s_ratio, v_ratio = rgb_to_hsv(r / 255.0, g / 255.0, b / 255.0)
            h, s, v = (h_ratio * 360, s_ratio * 255, v_ratio * 255)

            min_h, min_s, min_v = GREEN_RANGE_MIN_HSV
            max_h, max_s, max_v = GREEN_RANGE_MAX_HSV
            if min_h <= h <= max_h and min_s <= s <= max_s and min_v <= v <= max_v:
                pix[x, y] = (0, 0, 0, 0)


    im.save(name + '.png')


if __name__ == '__main__':
    remove_green_background()

然后您就可以在使用模仿工具时使用它

答案 1 :(得分:0)

您无需添加其他依赖项,就可以将@Mock注释替换为某个地方的辅助函数:

inline fun <reified T> mock(): T =
        Mockito.mock(T::class.java)

// To avoid having to use backticks for "when"
fun <T> whenever(methodCall: T): OngoingStubbing<T> =
        Mockito.`when`(methodCall)

然后在您的测试中:

val heroesRepository: HeroesRepository = mock()

@Test
fun yourTest() {
    whenever(heroesRepository.getHeroes(ArgumentMatchers.anyInt()))
        .thenReturn(heroesPublishSubject.singleOrError())
}

就像以前一样。这应该行得通,因为您不希望Mockito处理@Mock lateinit var(似乎很麻烦),而是自己实例化该模拟。

答案 2 :(得分:0)

FWIW,when 语句只是调用实际函数的原因是因为函数本身 (getHeroes) 没有标记为 open

因此,即使该类是非 final 的,该方法也是 final 的,不会被模拟。