简体   繁体   English

Mockk,如何模拟在私有函数中使用的 JSONObject 构造函数

[英]Mockk, How to mock JSONObject constructor which is used inside a private function

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

having a class MetaData built through api fun from(intent: Intent?): MetaData?有一个通过 api fun from(intent: Intent?): MetaData?构建的类MetaData fun from(intent: Intent?): 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
            }
        }
    }
}

would like to test the code path which throws JSONException and NullPointerException .想测试抛出JSONExceptionNullPointerException的代码路径。

Have tried this test the and it can test the null path from intent.getStringExtra("meta")已经尝试过这个测试,它可以测试来自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)
    }

How to make this test to step into the getMetaDataJson(json) , I guess that needs to not mocking the Intent but the JSONObject constructor (how)?如何使这个测试进入getMetaDataJson(json) ,我想不需要模拟 Intent 而是 JSONObject 构造函数(如何)?

Or is it possible to stub the fun getMetaDataJson(json: String) but no matter what the input is it should replace the input json string to some configured test data?或者是否可以存根fun getMetaDataJson(json: String)但无论输入是什么,它都应该将输入的json字符串替换为一些配置的测试数据?

How to test the two exception path?如何测试两个异常路径?

/**
 * 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));
}

The JSONObject construct will throw an exception if the passed string is not valid.如果传递的字符串无效,JSONObject 构造将抛出异常。 Just pass a random string like "This random: String" and you should get the JSONException .只需传递一个像"This random: String" ,你就会得到JSONException

Regarding the NullPointerException you should not guard for this exception since the constructor doesn't throw it.关于NullPointerException你不应该保护这个异常,因为构造函数不会抛出它。

You can try with Constructor mock .您可以尝试使用Constructor mock It's available from mockk 1.11.0它可以从mockk 1.11.0

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM