Kotlin功能参数和对象的单元测试 [英] Kotlin Unit Testing for Function Parameter and Object

查看:143
本文介绍了Kotlin功能参数和对象的单元测试的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在Kotlin中,我们可以具有函数对象并作为函数参数传递.

In Kotlin,, we could have function object and pass in as function parameter.

  1. 如何创建单元测试来测试功能对象的逻辑? (例如下面的funcParam)
  2. 如何对具有功能参数的功能进行单元测试? (例如下面的functionWithFuncParam)-即我可以为funcParam创建一个模拟文件吗?

  1. How to create unit test to test the function object logic? (e.g. funcParam below)
  2. How to unit test the function that has function parameter? (e.g. functionWithFuncParam below) - i.e. can I create a Mock for funcParam?

class MyClass1(val myObject: MyObject) {
    val funcParam = fun (num: Int): Int {
        return num * num
    }

    fun myFunctionOne() {
        myObject.functionWithFuncParam(funcParam)
    }
}

class MyObject () {
    fun functionWithFuncParam(funcParam: (Int) -> Int) {
        println(funcParam(32))
    }
}

推荐答案

假设funcParampublic,则可以有意地将其测试为任何其他方法:

Assuming funcParam is public intentionally you can test it as any other method:

class MyClass1Tests {
    val sut = MyClass1(MyObject())

    @Test
    fun `funcParam multiplies input`() {
        assertThat(sut.funcParam(4), equalTo(16))
        assertThat(sut.funcParam(1), equalTo(1))
        assertThat(sut.funcParam(0), equalTo(0))
        assertThat(sut.funcParam(-10), equalTo(100))
    }
}

如果funcParam是私有的,则不应直接测试其行为,而只能通过其包含类的公共接口进行测试.

If funcParam is private you shouldn't test its behavior directly but only through public interface of it's containing class.

在测试functionWithFuncParam时,您可以轻松提供(Int) -> Int的存根实现:

When testing functionWithFuncParam you can easily supply a stub implementation of (Int) -> Int:

class MyObjectTests {
    val outContent = ByteArrayOutputStream().apply {
        System.setOut(PrintStream(this))
    }
    val sut = MyObject()
    @Test
    fun `functionWithFuncParam prints function output `() {
        sut.functionWithFuncParam { 12345678  }
        assertThat(outContent.toString(), containsString("12345678"))
    }
}

如果您想测试与MyObjectMyClass1交互,一种方法是使用MyClass1中由MyObject实现的接口.通常,如果2个类是截然不同的协作者,则最好的选择是从某种意义上说,它们具有独立的,几乎不相关的行为:

If you'd like to test MyClass1 interaction with MyObject one way is to use interface implemented MyObject by in MyClass1. Usually the best choice if 2 classes are distinct collaborators in a sense that they have separate mostly unrelated behaviour:

interface FunctionalObj {
    fun functionWithFuncParam(funcParam: (Int) -> Int)
}
class MyClass1(val myObject: FunctionalObj) {
//omitted for brevity
}
class MyClass1Tests {
    var params = mutableListOf<(Int)->Int>()
    val sut = MyClass1(object: FunctionalObj {
        override fun functionWithFuncParam(funcParam: (Int) -> Int) { params.add(funcParam) }
    })

    @Test
    fun `myFunctionOne calls delegate`() {
        sut.myFunctionOne()
        assertThat(params.size, equalTo(1))
        assertThat(params[0], equalTo(sut.funcParam))//only if `funcParam` is public
    }
}

如果MyClass1MyObject的交互更为复杂(即涉及更多调用,则

If MyClass1 and MyObject interaction is more complex (i.e. involves more calls both queries and commands) it would imply that they are peers working together closely. In such case, using mocks can lead to brittle and hard to write tests.

这篇关于Kotlin功能参数和对象的单元测试的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆