単体テストに必要なモジュール
以下のモジュールがテスト実行環境に必要。
- appengine-local-runtime
- appengine-api-stubs.jar
Eclipse Plug-inを導入した場合は、"${ECLIPSE_HOME}/plugins/com.google.appengine.eclipse.sdkbundle_1.2.0.v200904062334/appengine-java-sdk-1.2.0/lib/impl"のようなフォルダに配置されている。バージョン番号を含んだフォルダ名なので、後々変わるかもしれない。mavenのリポジトリでは"http://www.mvnsearch.org/maven2/com/google/appengine/"配下のフォルダにあるのでここから拾えば良い。
テスト実行環境用のAPIプロキシの実装クラスを準備する
package com.shin1ogawa; import com.google.apphosting.api.ApiProxy; public class TestEnvironment implements ApiProxy.Environment { public String getAppId() { return "Unit Tests"; } public String getVersionId() { return "1.0"; } public void setDefaultNamespace(String s) {} public String getRequestNamespace() { return null; } public String getDefaultNamespace() { return null; } public String getAuthDomain() { return null; } public boolean isLoggedIn() { return true; } public String getEmail() { return null; } public boolean isAdmin() { return false; } }
com.google.appengine.api.users.UserServiceFactory#getUserService()からcom.google.appengine.api.users.Userオブジェクトを取得してテストに使用するのであれば、isLoggedIn()でtrueを返し、getAuthDomain()とgetEmail()でnull以外を返してやれば良い。
テストクラスを作成する - その1
まずは@Beforeと@Afterだけ。
package com.shin1ogawa.service; import static org.junit.Assert.assertEquals; import java.io.File; import java.util.List; import org.junit.After; import org.junit.Before; import org.junit.Test; import com.google.appengine.api.datastore.dev.LocalDatastoreService; import com.google.appengine.api.users.User; import com.google.appengine.api.users.UserServiceFactory; import com.google.appengine.tools.development.ApiProxyLocalImpl; import com.google.apphosting.api.ApiProxy; import com.shin1ogawa.TestEnvironment; import com.shin1ogawa.entity.Board; public class BoardServiceTest { @Before public void setUp() { ApiProxy.setEnvironmentForCurrentThread(new TestEnvironment()); ApiProxy.setDelegate(new ApiProxyLocalImpl(new File("target/testDataStore")) { }); ApiProxyLocalImpl proxy = (ApiProxyLocalImpl) ApiProxy.getDelegate(); proxy.setProperty(LocalDatastoreService.NO_STORAGE_PROPERTY, Boolean.TRUE.toString()); } @After public void tearDown() { ApiProxyLocalImpl proxy = (ApiProxyLocalImpl) ApiProxy.getDelegate(); LocalDatastoreService datastoreService = (LocalDatastoreService) proxy .getService("datastore_v3"); datastoreService.clearProfiles(); ApiProxy.setDelegate(null); ApiProxy.setEnvironmentForCurrentThread(null); } }
"new ApiProxyLocalImpl(new File("target/testDataStore")) {}"としているが、ここで指定したフォルダ配下にローカルストレージ用のファイルと使用したインデックスが配置される。ただし、今回はApiProxyへの設定で"LocalDatastoreService.NO_STORAGE_PROPERTY"を"true"に設定しているので、実際のファイルへの保存は行われない。あらかじめテストデータが格納された状態でのテストを行いたい場合は、この設定を"false"にした状態でデータの書き込みを行い、それをテストケース毎に保存しておくと良い。
テストクラスを作成する - その2
次に実際のテストクラス。今回は"Board"というEntityクラスと、それに関するアクセサを提供する"BoardService"というクラスがある事を想定して、そのServiceクラスのテストケースとして記述している。こんなカンジで、実際のテストメソッド内では特に特殊な事は何も必要無い。
@Test public void create01() { User user = UserServiceFactory.getUserService().getCurrentUser(); BoardService test = new BoardService(); Board board = test.create(user, "test title1"); List<Board> list = test.list(); assertEquals(1, list.size()); assertEquals("test title1", board.getTitle()); } @Test public void delete01() { User user = UserServiceFactory.getUserService().getCurrentUser(); BoardService test = new BoardService(); Board board1 = test.create(user, "test title1"); Board board2 = test.create(user, "test title2"); List<Board> list = test.list(); assertEquals(2, list.size()); assertEquals("test title1", board1.getTitle()); assertEquals("test title2", board2.getTitle()); test.delete(board1); list = test.list(); assertEquals(1, list.size()); assertEquals("test title2", list.get(0).getTitle()); }
注意点
上記の内容については「Googleが提供しているEclipseのPlug-inでプロジェクトを作成し、自分に必要なライブラリをEclipse的にAdd Build pathした環境」で動作するためのもの。MavenとEclipseを組み合わせているとはまる可能性大。自分はそれではまった。MavenからEclipseプロジェクトを作成していると、datanucleus-core内のモジュールがCLASSPATHに重複しているとなんだかエラーが出てしまい、JDOのモデルクラスのエンハンスが正しく行われなかったり、まぁ色々あったりする。
ただし、Mavenからの単体テストの実行もうまくできる方法がわかっているので、それも後で書く。
0 件のコメント:
コメントを投稿