java - 为什么我的 JSONObject 相关单元测试失败?

标签 java android unit-testing android-gradle-plugin

我正在使用 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 EST

我发现我可以使用 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;
}

出于某种原因,“没有 key ???”打印出来了?!?!?!?!为什么?!

编辑下午 6:20 EST

我已经弄清楚如何调试单元测试。根据调试器,分配的 JSONObject 正在返回 "null"。我不知道这意味着什么(见下文)。由于我认为这是相关的,我的 gradle 文件包括以下内容:

testOptions {
    unitTests.returnDefaultValues = true
}

这特别奇怪,因为如果我在测试中构造一个 JSONObject,那么一切正常。但如果它是原始应用程序代码的一部分,则它不起作用并执行上述操作。

enter image description here

最佳答案

正如 Lucas 所说,JSON 与 Android SDK bundle 在一起,因此您使用的是 stub 。

目前的解决方案是从 Maven Central 中提取 JSON,如下所示:

dependencies {
    ...
    testImplementation 'org.json:json:20210307'
}

您可以将版本 20210307 替换为 the latest one取决于 Android API。是not known哪个版本的 maven artefact 与 Android 附带的完全/最接近。

或者,您可以下载并包含 jar:

dependencies {
    ...
    testImplementation files('libs/json.jar')
}

请注意,您还需要使用 Android Studio 1.1 或更高版本,并且至少需要 22.0.0 或更高版本的构建工具才能正常工作。

相关问题:#179461

关于java - 为什么我的 JSONObject 相关单元测试失败?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32385092/

相关文章:

javascript - react-native-router-flux 不路由

java - 排除包含 IntelliJ Idea 中内置源的文件夹

c# - 流利的断言 : Approximately compare a classes properties

javascript - 有没有办法在自定义匹配器中使用 Jasmine 默认匹配器?

java - Apache Solr 处理数十万个请求

java - 使用android intent从服务器打开pdf文件

java - ArrayList - 合并排序

java - #define 中的 JNA 宏函数

android - 将 Amazon RDS 与 Android 应用程序结合使用

android - 如何在 android Activity 完成后刷新 fragment ?