_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);
_
ただし、上記の2つの要求は失敗します。スタックトレースは、channelAssertionとmessageAssertionがnullであると言っていますが、理由はわかりません。私の質問は:上記の2つのアサートが失敗するのはなぜですか?
以下は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)
_
EST 5:55 PM 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;
}
_
何らかの理由で、「キーがありませんか????」印刷中ですか?!?!?!?!なぜ?!
EST 6:20 PM EST
単体テストをデバッグする方法を見つけました。デバッガーによると、割り当てられたJSONObjectは_"null"
_を返しています。私はこれが何を意味するのか見当がつかない(以下を参照)。これは関連があると思うので、私のgradleファイルには次のものが含まれています。
_testOptions {
unitTests.returnDefaultValues = true
}
_
テスト内でJSONObjectを作成すると、すべてが正常に機能するため、特に奇妙です。しかし、元のアプリケーションのコードの一部である場合、機能せず、上記のようになります。
クラスJSONObjectはAndroid SDKの一部です。つまり、デフォルトでは単体テストに使用できません。
http://tools.Android.com/tech-docs/unit-testing-support から
単体テストの実行に使用されるAndroid.jarファイルには、実際のコードが含まれていません-実際のデバイスのAndroidシステムイメージ。代わりに、すべてのメソッドが例外をスローします(デフォルト)これは、ユニットテストがコードのみをテストし、Androidプラットフォーム(Mockitoを使用して明示的にモックされていないことなど)の特定の動作に依存しないことを確認するためです。
テストオプションを設定するとき
_testOptions {
unitTests.returnDefaultValues = true
}
_
「方法...モックされていません」を修正しています。問題ですが、結果は、コードがnew JSONObject()
を使用する場合、実際のメソッドを使用せず、何もしないモックメソッドを使用し、デフォルト値を返すだけです。それがオブジェクトがnull
である理由です。
この質問で問題を解決するさまざまな方法を見つけることができます: Mockitoを使用する場合、Androidメソッドはモックされません
Lucasが言うように、JSONはAndroid SDKにバンドルされているため、スタブで作業しています。
現在の解決策は、次のようにMaven CentralからJSONをプルすることです。
dependencies {
...
testCompile 'org.json:json:20180130'
}
または、jarをダウンロードして含めることができます。
dependencies {
...
testCompile files('libs/json.jar')
}
不明 Mavenアーティファクトのどのバージョンが、Androidに同梱されているものと正確に/最も密接に対応しています。
これが機能するためには、Android Studio 1.1以上、少なくともビルドツールバージョン22.0.0以上を使用する必要があることに注意してください。
関連問題: #179461
さて、私の最初の予想は、getMessage()
メソッドがnull
を返すことです。あなたの質問でそのメソッドの本体を表示して答えを見つけることができますが、おそらくブレークポイントを使用してAndroidアプリケーションをデバッグする方法を研究する必要があります。
これにより、コードをステップごとに実行し、各ステップで各変数の値を確認できます。それはあっという間にあなたの問題を示し、それはあなたがプログラミングに真剣に関与するつもりなら、できるだけ早く間違いなく習得すべきスキルです。