昨日の記事をちょっと手を動かしておこうと思って、IntentのUnitTestを書いてみた。ついでに、@RunWith(AndroidJUnit4.class)を有効にして。
AndroidJUnit4.classを使うにあたってエラーが出て修正したポイントは2つ。あとおまけで1つ。
- injectInstrumentationによるInstrumentationへのinject
- これしないと、super.setUp()で落ちる
- InstrumentationRegistry.getInstrumentation().runOnMainSync()によるintentからのActivityの起動
- これしないと、startActivityがヌルポで落ちる
- ContextThemeWrapperを使うことで、R.style.AppThemeをテスト時にレイアウトとして使う
- レイアウトを独自でカスタマイズしている場合、AppThemeが無いみたいなエラーが出てきました
- どうやら、ContextThemeWrapperで仮のレイアウトを使うことで回避できるもよう
- 今回はあくまでもintentの確認なので、まー、よしですかね
UIスレッドの話しなんかも、対応を終えたあとはなるほどなーという感じ。
ちょっと記述量を減らしたく、ButterKnifeを使ってみました。おまけ程度。
内容は、
- com.example.activityのアクティビティを起動する
- 表示されるボタンをタップして、別アクティビティ(com.example.activity.Next)を起動する
という内容に対して、期待したintentが飛ぶことを確認する、というものです。
ActivityUnitTestCaseなので、その実際が描画されたりはしません。これ、Integrationレベルで確認すると、Espressoを使って描画ベースの存在確認を行いますね。
package com.example.activity;
import android.app.Activity;
import android.content.Intent;
import android.support.test.InstrumentationRegistry;
import android.support.test.runner.AndroidJUnit4;
import android.test.ActivityUnitTestCase;
import android.view.ContextThemeWrapper;
import android.widget.Button;
import com.example.R;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import butterknife.ButterKnife;
import butterknife.InjectView;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.notNullValue;
import static org.junit.Assert.assertThat;
@RunWith(AndroidJUnit4.class)
public class MainActivityUnitTest extends ActivityUnitTestCase<MainActivity> {
private Activity activity;
private Intent intent;
public MainActivityUnitTest() {
super(MainActivity.class);
}
@InjectView(R.id.test_button) Button testButton;
@Before
@Override
public void setUp() throws Exception {
injectInstrumentation(InstrumentationRegistry.getInstrumentation());
super.setUp();
ContextThemeWrapper context = new ContextThemeWrapper(InstrumentationRegistry.getTargetContext(), R.style.AppTheme);
setActivityContext(context);
intent = new Intent(context, MainActivity.class);
InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
@Override
public void run() {
activity = startActivity(intent, null, null);
}
});
ButterKnife.inject(activity);
}
@Test
public void startTopButtonActivityLaunchViaWebhookDebugButton() {
testButton.performClick();
Intent triggeredIntent = getStartedActivityIntent();
assertThat(triggeredIntent, is(notNullValue()));
assertThat(triggeredIntent.toString(),
is(new Intent().setClassName(
"com.example",
"com.example.activity.Next").toString()));
}
ふぅ。Intent、いろいろちゃんとしておかないと魔の巣窟になって危なそうですね。サービスが肥大化してくると特に。怖い怖い。
最近、StethoをVolleyに適用しようとしています。単純に適用しようとすると、VolleyのHttpStackを活用してOkHttpStackのようなクラスを作成し、QueueRequestにHttpStackを与えます。
なのですが、今取り組んでいるところはそのような形でさくっとできるような所ではなく、少し手惑い気味。