使用 Kotlin 数据类的 Json 解析器正确返回 json 数据,但是为啥解析器(MockK)的单元测试会失败?

Posted

技术标签:

【中文标题】使用 Kotlin 数据类的 Json 解析器正确返回 json 数据,但是为啥解析器(MockK)的单元测试会失败?【英文标题】:Json parser using Kotlin Data Class correctly returns json data, but why does unit testing of parser (MockK) fail?使用 Kotlin 数据类的 Json 解析器正确返回 json 数据,但是为什么解析器(MockK)的单元测试会失败? 【发布时间】:2021-05-23 19:49:30 【问题描述】:

我有一个非常简单的 JSON 解析器,它使用 Kotlin 数据类,并且运行良好。但是,当我尝试对解析器方法 (MockK) 进行单元测试时,断言失败,因为模型对象返回 NULL 值。我是 Kotlin 和 MockK 的新手,所以请帮我确定我哪里出错了。

用于此目的的所有文件/类如下:

data.json "name":"john","age":22,"subject":"engineering"

parser.kt

interface Parser 
    fun parseJson(jsonObject: JSONObject)

Student.kt

data class Student(
    var name: String? = null,
    var age: Int? = null,
    var subject: String? = null
) : Parser 

    override fun parseJson(jsonObject: JSONObject) 
        jsonObject?.let 
            name = it.getString("name")
            age = it.getInt("age")
            subject = it.getString("subject")
        
    

MainActivity - 从 data.json 读取、解析并记录结果的简单方法

private fun readJson() 
    val inputStream = (assets.open("data.json"))
    val buffer = ByteArray(inputStream.available())
    inputStream.read(buffer)
    inputStream.close()
    val jsonData = JSONObject(String(buffer, StandardCharsets.UTF_8))

    val student = Student()
    student.parseJson(jsonData)
    Log.d("TAG", student.name + " " + student.age + " " + student.subject) // RETURNS CORRECT DATA

StudentTest.kt

class StudentTest 
    private lateinit var student: Student

    @Before
    fun setUp() 
        MockKAnnotations.init(this, relaxed = true)
        student = Student()
    

    @Test
    fun `test parser`() 
        student.parseJson(JSONObject(DATA))
        assertEquals("mary", student.name) // ASSERTION FAILS - student.name returns NULL
    

    private companion object 
        const val DATA = "\"name\":\"mary\",\"age\":21,\"subject\":\"history\""
    

任何帮助将不胜感激。 提前谢谢大家。

【问题讨论】:

欢迎堆栈溢出。我已经删除了您在帖子开头的文字,因为您的问题非常好并且可以理解,希望您能找到答案 【参考方案1】:

看来您实际上并不需要对此测试进行模拟。除非您问题中的代码不完整。

简化示例:

@Test
fun `test parser`() 
    val student = Student()
    student.parseJson(JSONObject("\"name\":\"mary\",\"age\":21,\"subject\":\"history\""))
    assertEquals("mary", student.name)

就像您的示例一样,这对名称进行断言。您创建一个Student 的实例,然后使用您的不可序列化字符串调用parseJson。断言成功。

如果这不能回答您的问题,请改写和/或添加更好的示例。 :)

【讨论】:

以上是关于使用 Kotlin 数据类的 Json 解析器正确返回 json 数据,但是为啥解析器(MockK)的单元测试会失败?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Retrofit 2.0 (Kotlin) 正确解析嵌套的 JSON 对象?

Kotlin入门(31)JSON字符串的解析

使用Gson解析Json

如何使用 Kotlin 序列化解析 JSON 对象列表中的第一个属性?

Gson 无法解析 Kotlin 中的字符串 json 格式数据

在 Kotlin 中使用 Moshi 和 Retrofit 解析具有增量对象名称的 JSON