【问题标题】:Mockk, How to mock JSONObject constructor which is used inside a private functionMockk,如何模拟在私有函数中使用的 JSONObject 构造函数
【发布时间】:2021-09-19 05:30:45
【问题描述】:

使用 mockk,testImplementation "io.mockk:mockk:1.9.3"

有一个通过 api fun from(intent: Intent?): MetaData? 构建的类 MetaData

class MetaData {

    @JvmField
    val rid: String
    ......

   private constructor(meta: JSONObject) {
        rid = meta.optString("RID", "")
    }

   companion object {

        @JvmStatic
        fun from(intent: Intent?): MetaData? {
            if (intent == null) {
                 return null
            }

            val metaJsonStr: String = intent.getStringExtra("meta") ?: return null
                   
            val rmeta = getMetaDataJson(metaJsonStr)
                ?: return null
                     
            return MetaData(meta)
        }
        
        private fun getMetaDataJson(json: String): JSONObject? {
            
            return try {
                JSONObject(json)
            } catch (e: JSONException) {
                System.out.println("+++ !!! 111 exp in getMetaDataJson(), $e")
                null
            } catch (e: NullPointerException) {
                System.out.println("+++ !!! 222 exp in getMetaDataJson(), $e")
                null
            }
        }
    }
}

想要测试抛出JSONExceptionNullPointerException 的代码路径。

已经尝试过这个测试,它可以测试来自intent.getStringExtra("meta")的空路径

@Test
    fun test_from_WhenCalledWithIntentWithNometa_ShouldReturnNull() {
        val intentMock: Intent = mockk<Intent>(relaxed = true)
        every { intentMock.getStringExtra(any()) } returns null
        val metaData = MetaData.from(intentMock)
        Assert.assertEquals(metaData, null)
    }

如何让这个测试步入getMetaDataJson(json),我想不需要模拟 Intent 而是 JSONObject 构造函数(如何)?

或者是否可以存根fun getMetaDataJson(json: String),但无论输入是什么,它都应该将输入json字符串替换为一些配置的测试数据?

如何测试两个异常路径?

【问题讨论】:

  • 这看起来应该永远被嘲笑。如果要测试异常路径,则传入会导致指定错误的字符串。

标签: android unit-testing kotlin mockk


【解决方案1】:
/**
 * Creates a new {@code JSONObject} with name/value mappings from the JSON
 * string.
 *
 * @param json a JSON-encoded string containing an object.
 * @throws JSONException if the parse fails or doesn't yield a {@code
 *     JSONObject}.
 */
public JSONObject(@NonNull String json) throws JSONException {
    this(new JSONTokener(json));
}

如果传递的字符串无效,JSONObject 构造将抛出异常。只需传递一个像"This random: String" 这样的随机字符串,你就应该得到JSONException

关于NullPointerException,你不应该注意这个异常,因为构造函数不会抛出它。

【讨论】:

    【解决方案2】:

    你可以试试Constructor mock。可以从mockk 1.11.0获得它

    【讨论】:

    • 不确定对于在要测试的成员函数中实例化对象的情况有什么帮助。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-08-19
    • 1970-01-01
    • 2019-11-24
    • 2016-12-28
    相关资源
    最近更新 更多