如何在 kotlin 中测试私有函数?

How to test a private function in kotlin?

我有两个对象远程模型和领域模型

远程模型

data class InstanceRemoteModel (
    val id: String,
    val containers: List<Container>,
    val operations: List<Operation>
)

data class ContainerRemoteModel (
    val id: String,
    val capacity: Long
)

data class OperationRemoteModel (
    val id: String,
    val weight: Long,
    val containerId: String
)

领域模型

data class Instance (
    val id: String,
    val containers: Map<String, Container>,
    val operations: Map<String, Operation>
)

data class Container (
    val id: String,
    val capacity: Long
    val total_weight: Long
)

data class Operation (
    val id: String,
    val weight: Long,
    val container: Container
)

然后我有一个 mapper 将对象从远程模型映射到域模型。在这里,我将专注于映射容器。请注意,域模型中的 Container 对象具有与 ContainerRemoteModel 不同的属性。操作也是一样。

object Mapper {
  fun toDomainModel(remoteInstance: InstanceRemoteModel): Instance {
    val containers : Map<String, Container> = mapContainers(remoteInstance)
    val operations : Map<String, Operation> = mapOperations(remoteInstance)
    return Instance(remoteInstance.id,containers,operations)
  }



  private fun  mapContainers(remoteInstance: InstanceRemoteModel) : Map<String, Container> {
    //do some computations
    val containers : List<Container> = remoteInstance.containers.map { cont -> Container(...)}
    return containers.associateBy({ it.id }, { it }
  }

  private fun mapOperations(remoteInstance: InstanceRemoteModel): Map<String, Operation> {
    ...
  }
}

我的问题是:如何正确测试映射器?请注意 mapOperationsmapContainers 是私有函数。

在单元测试中,您只需要测试 public 个方法! 如果测试 class public 函数未涵盖私有函数,则该函数是一个孤岛,没有人使用它,编译器将对此发出警报。

been 说如果你还想测试这个功能

您可以使用反射来访问您想要的任何字段

通过添加此依赖项

<dependency>
    <groupId>org.jetbrains.kotlin</groupId>
    <artifactId>kotlin-reflect</artifactId>
    <version>1.4.20</version>
    <scope>runtime</scope>
</dependency>

那你就可以测试一下了

class MapperTest : TestCase(){

    @Test
    fun `test private method`(){
        val input = InstanceRemoteModel("test", emptyList(), emptyList())
        val returnValue = Mapper.invokePrivateFunction("mapContainers",input) as Map<String, Container>
        assert(returnValue.isEmpty())
    }

    inline fun <reified T> T.invokePrivateFunction(name: String, vararg args: Any?): Any? =
        T::class
            .declaredMemberFunctions
            .firstOrNull { it.name == name }
            ?.apply { isAccessible = true }
            ?.call(this, *args)
}