2012年3月14日水曜日

Slim3のテストを行う時に気をつけること(Datastore編)

開発しているGAEのアプリケーションのデータのメンテナンスを行う必要があるので、
メンテナンス用のコントローラを作成してテストを行おうと思って、テストコードを
書いていました。

テストコードをそのまま掲載するわけにはいかないので、適当なコードを載せます。

public class HogeControllerTest extends ControllerTestCase {
     private HogeService service = new HogeService();

    @Override
    public void setUp() throws Exception {
        super.setUp();

        // データの登録
        Hoge hoge = new Hoge();
        hoge.setId(1);
        hoge.setName("abcd");

        service.put(hoge);
    }

    @Test
    public void run() throws Exception {
        ApiProxy.setEnvironmentForCurrentThread(new UnitTestEnvironment());
        
        tester.start("/hoge");
        HogeController controller = tester.getController();
        assertThat(controller, is(notNullValue()));
        assertThat(tester.isRedirect(), is(false));
        assertThat(tester.getDestinationPath(), is(nullValue()));
        
        List<Hoge> list = service.query().asList();
        assertEquals(1, list.size());                     // ここでエラー
    }
}

UnitTestEnvironmentクラスのソースです。
public class UnitTestEnvironment implements Environment {

    @Override
    public String getAppId() {
        return "Unit Tests";                // setupを使う場合はこれにしておかないとquery()でデータが取れない。
    }

    @Override
    public Map<string, object> getAttributes() {
        Map<string, object> map = new HashMap<string, object>();
        map.put("com.google.appengine.server_url_key", "dummy");
        return map;
    }

    @Override
    public String getAuthDomain() {
        return "gmail.com";
    }

    @Override
    public String getEmail() {
        return "admin@gmail.com";
    }

    @Override
    public String getRequestNamespace() {
        return "";
    }

    @Override
    public String getVersionId() {
        return "unittest";
    }

    @Override
    public boolean isAdmin() {
        return true;
    }

    @Override
    public boolean isLoggedIn() {
        return true;
    }

}

上記のUnitTestEnvironmentだとテストは正常終了します。
これは、setupでのデータストアの書き込み時のapplicationIdと
テスト実行時の呼び出しの時のapplicationIdが一致するからです。

失敗していた時というのが、TaskQueueのテストをしようとして参考にした
UnitTestEnvironmentのapplicationIdが"MyApplicationId"とかにしていたので
setUpの時とapplicationIDが異なってしまっていました。
その影響で、何度queryを実行してもデータが1件も取れないという状況に
陥っていました。

なので、setupを使う時というか、データストアを使ったテストを行う場合は
以下の点に注意した方が良さそうです。

  1. appidをデータ登録時と参照時で合わせておく。
  2. Slim3のTestEnvironment.javaで設定されているappIdは"Unit Tests"

2.はsetupを使わず、自分でデータを登録する場合は問題ないと思いますが、
初期データなど使う場合や、事前にlocal_db.binを用意する場合などは
気をつけておかないとデータが取れない現象に遭遇するかもしれません。

以下、参考までに当時の私のG+に投稿したコメントです。

TaskQueueに入っている事を確認するテストで苦戦している様子(Google+)
https://plus.google.com/u/0/114183076079015753160/posts/NUceVDbNKDK

データストアからフィルタなしのqueryでデータが取れなくて苦戦している様子(Google+)
https://plus.google.com/u/0/114183076079015753160/posts/MZhuGtjrwTS