[英]Why is my JSONObject related unit test failing?
我正在使用gradle testFlavorType
運行我的測試
JSONObject jsonObject1 = new JSONObject();
JSONObject jsonObject2 = new JSONObject();
jsonObject1.put("test", "test");
jsonObject2.put("test", "test");
assertEquals(jsonObject1.get("test"), jsonObject2.get("test"));
以上測試成功。
jsonObject = new SlackMessageRequest(channel, message).buildBody();
String channelAssertion = jsonObject.getString(SlackMessageRequest.JSON_KEY_CHANNEL);
String messageAssertion = jsonObject.getString(SlackMessageRequest.JSON_KEY_TEXT);
assertEquals(channel, channelAssertion);
assertEquals(message, messageAssertion);
但是上面兩個請求都失敗了。 堆棧跟蹤說 channelAssertion 和 messageAssertion 為空,但不確定為什么。 我的問題是:為什么上述兩個斷言失敗?
下面是SlackMessageRequest
。
public class SlackMessageRequest
extends BaseRequest {
// region Variables
public static final String JSON_KEY_TEXT = "text";
public static final String JSON_KEY_CHANNEL = "channel";
private String mChannel;
private String mMessage;
// endregion
// region Constructors
public SlackMessageRequest(String channel, String message) {
mChannel = channel;
mMessage = message;
}
// endregion
// region Methods
@Override
public MethodType getMethodType() {
return MethodType.POST;
}
@Override
public JSONObject buildBody() throws JSONException {
JSONObject body = new JSONObject();
body.put(JSON_KEY_TEXT, getMessage());
body.put(JSON_KEY_CHANNEL, getChannel());
return body;
}
@Override
public String getUrl() {
return "http://localhost:1337";
}
public String getMessage() {
return mMessage;
}
public String getChannel() {
return mChannel;
}
// endregion
}
以下是堆棧跟蹤:
junit.framework.ComparisonFailure: expected:<@tk> but was:<null>
at junit.framework.Assert.assertEquals(Assert.java:100)
at junit.framework.Assert.assertEquals(Assert.java:107)
at junit.framework.TestCase.assertEquals(TestCase.java:269)
at com.example.app.http.request.SlackMessageRequestTest.testBuildBody(SlackMessageRequestTest.java:30)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:483)
at junit.framework.TestCase.runTest(TestCase.java:176)
at junit.framework.TestCase.runBare(TestCase.java:141)
at junit.framework.TestResult$1.protect(TestResult.java:122)
at junit.framework.TestResult.runProtected(TestResult.java:142)
at junit.framework.TestResult.run(TestResult.java:125)
at junit.framework.TestCase.run(TestCase.java:129)
at junit.framework.TestSuite.runTest(TestSuite.java:252)
at junit.framework.TestSuite.run(TestSuite.java:247)
at org.junit.internal.runners.JUnit38ClassRunner.run(JUnit38ClassRunner.java:86)
at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecuter.runTestClass(JUnitTestClassExecuter.java:86)
at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecuter.execute(JUnitTestClassExecuter.java:49)
at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassProcessor.processTestClass(JUnitTestClassProcessor.java:64)
at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.processTestClass(SuiteTestClassProcessor.java:50)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:483)
at org.gradle.messaging.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:35)
at org.gradle.messaging.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
at org.gradle.messaging.dispatch.ContextClassLoaderDispatch.dispatch(ContextClassLoaderDispatch.java:32)
at org.gradle.messaging.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:93)
at com.sun.proxy.$Proxy2.processTestClass(Unknown Source)
at org.gradle.api.internal.tasks.testing.worker.TestWorker.processTestClass(TestWorker.java:106)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:483)
at org.gradle.messaging.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:35)
at org.gradle.messaging.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
at org.gradle.messaging.remote.internal.hub.MessageHub$Handler.run(MessageHub.java:360)
at org.gradle.internal.concurrent.DefaultExecutorFactory$StoppableExecutorImpl$1.run(DefaultExecutorFactory.java:64)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
編輯美國東部時間下午 5:55
我發現我可以使用System.out.println("")
登錄,然后通過運行gradle testFlavorType --debug
查看結果,通過反復試驗我發現了以下奇怪的情況:
@Override
public JSONObject buildBody() throws JSONException {
System.out.println("buildBody mChannel = " + mChannel);
System.out.println("buildBody mMessage = " + mMessage);
JSONObject body = new JSONObject();
body.put(JSON_KEY_TEXT, getMessage());
body.put(JSON_KEY_CHANNEL, getChannel());
if (body.length() != 0) {
Iterator<String> keys = body.keys();
if (keys.hasNext()) {
do {
String key = keys.next();
System.out.println("keys: " + key);
} while (keys.hasNext());
}
} else {
System.out.println("There are no keys????");
}
return body;
}
出於某種原因,“沒有鑰匙???” 打印出來了嗎?!?!?!?! 為什么?!
編輯東部時間下午 6:20
我已經想出了如何調試單元測試。 根據調試器,分配的 JSONObject 返回"null"
。 我不知道這意味着什么(見下文)。 由於我認為這是相關的,因此我的 gradle 文件包含以下內容:
testOptions {
unitTests.returnDefaultValues = true
}
這特別奇怪,因為如果我在測試中構造一個 JSONObject,那么一切正常。 但如果它是原始應用程序代碼的一部分,則它不起作用並執行上述操作。
正如 Lucas 所說,JSON 與 Android SDK 捆綁在一起,因此您正在使用存根。
當前的解決方案是從 Maven Central 中提取 JSON,如下所示:
dependencies {
...
testImplementation 'org.json:json:20201115'
}
您可以根據 Android API 將20201115
版本替換為最新版本。 不知道哪個版本的 maven 人工制品與 Android 附帶的版本完全/最接近。
或者,您可以下載並包含 jar:
dependencies {
...
testImplementation files('libs/json.jar')
}
請注意,您還需要使用 Android Studio 1.1 或更高版本以及至少 22.0.0 或更高版本的構建工具才能使其工作。
相關問題: #179461
類 JSONObject 是 android SDK 的一部分。 這意味着默認情況下不可用於單元測試。
來自http://tools.android.com/tech-docs/unit-testing-support
用於運行單元測試的 android.jar 文件不包含任何實際代碼 - 由真實設備上的 Android 系統映像提供。 相反,所有方法都會拋出異常(默認情況下)。 這是為了確保您的單元測試僅測試您的代碼,而不依賴於 Android 平台的任何特定行為(您沒有明確模擬,例如使用 Mockito)。
當您將測試選項設置為
testOptions {
unitTests.returnDefaultValues = true
}
您正在修復“方法......沒有被嘲笑”。 問題,但結果是,當您的代碼使用new JSONObject()
您並沒有使用真正的方法,而是使用了一個什么都不做的模擬方法,它只返回一個默認值。 這就是對象為null
的原因。
你可以在這個問題中找到解決問題的不同方法: Android methods are not mocked when using Mockito
好吧,我的第一個預感是您的getMessage()
方法返回null
。 您可以在問題中顯示該方法的主體,讓我們為您找到答案,但您可能應該研究如何使用斷點調試 android 應用程序。
這樣您就可以逐步運行您的代碼並查看每一步中每個變量的值。 這將立即向您展示您的問題,如果您打算認真參與編程,那么您絕對應該盡快掌握這項技能。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.