単体テストに必要なモジュール
以下のモジュールがテスト実行環境に必要。
- 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 件のコメント:
コメントを投稿