参考:Unit Testing With Local Service Implementations - Google App Engine - Google Code
1.テスト実行環境を作る
まずは、appengine-api-stubs.jarとappengine-local-runtime.jarへクラスパスを通す。これらはappengineのsdkをダウンロードしたフォルダのlib/implの下にあります。
2009.09.14追記:appengine-local-runtime.jarをWEB-INF/lib下に配置しておくと、ローカルでのGAE/Jサーバーの起動に失敗します。jarはlib以外に配置してください。詳しくは「ローカルでGAEサーバーが動かなくなった?!」
その後、上記ページを参考にして(というか、そっくりコピペして)、TestEnvironmentクラスを作成。
import com.google.apphosting.api.ApiProxy;
import java.util.HashMap;
import java.util.Map;
class TestEnvironment implements ApiProxy.Environment {
 public String getAppId() {
  return "test";
 }
 public String getVersionId() {
  return "1.0";
 }
 public String getEmail() {
  throw new UnsupportedOperationException();
 }
 public boolean isLoggedIn() {
  throw new UnsupportedOperationException();
 }
 public boolean isAdmin() {
  throw new UnsupportedOperationException();
 }
 public String getAuthDomain() {
  throw new UnsupportedOperationException();
 }
 public String getRequestNamespace() {
  return "";
 }
 public Map<String, Object> getAttributes() {
  return new HashMap<String, Object>();
 }
}
2.基本クラスを作成
1で作成したTestEnvironmentを継承してLocalServiceTestCaseクラスを作る。ローカルサービスを簡単にテストできるようにするための基本クラス。
import java.io.File;
import com.google.appengine.tools.development.ApiProxyLocalImpl;
import com.google.apphosting.api.ApiProxy;
import junit.framework.TestCase;
public class LocalServiceTestCase extends TestCase {
 @Override
 public void setUp() throws Exception {
  super.setUp();
  ApiProxy.setEnvironmentForCurrentThread(new TestEnvironment());
  ApiProxy.setDelegate(new ApiProxyLocalImpl(new File(".")) {
  });
 }
 @Override
 public void tearDown() throws Exception {
  // not strictly necessary to null these out but there's no harm either
  ApiProxy.setDelegate(null);
  ApiProxy.setEnvironmentForCurrentThread(null);
  super.tearDown();
 }
}
3.Datastore Testのための拡張クラス作成
今回、テスト目的がデータストアのチェックだったので、データストアの中身をチェックする時、毎回データをクリーンにしてからテストが実行できるように、LocalServiceTestCaseを継承した以下のようなLocalDatastoreTestCaseクラスも作成。
import com.google.appengine.api.datastore.dev.LocalDatastoreService;
import com.google.appengine.tools.development.ApiProxyLocalImpl;
import com.google.apphosting.api.ApiProxy;
public class LocalDatastoreTestCase extends LocalServiceTestCase {
 @Override
 public void setUp() throws Exception {
  super.setUp();
  ApiProxyLocalImpl proxy = (ApiProxyLocalImpl) ApiProxy.getDelegate();
  proxy.setProperty(LocalDatastoreService.NO_STORAGE_PROPERTY,
    Boolean.TRUE.toString());
 }
 @Override
 public void tearDown() throws Exception {
  ApiProxyLocalImpl proxy = (ApiProxyLocalImpl) ApiProxy.getDelegate();
  LocalDatastoreService datastoreService = (LocalDatastoreService) proxy
    .getService("datastore_v3");
  datastoreService.clearProfiles();
  super.tearDown();
 }
}
4.TestCaseを書いてみよう
ここまで終わってようやく自分のテストケースを実行できるようになりました。早速テストケースを書いて実行してみます。3で作ったLocalDatastoreTestCaseを継承して作ります。
import com.google.appengine.api.datastore.DatastoreServiceFactory;
import com.google.appengine.api.datastore.Query;
import hoge.Mutter;
import hoge.rpc.MutterUtils;
import hoge.test.LocalDatastoreTestCase;
public class TestMutterUtils extends LocalDatastoreTestCase {
 public void testAdd() {
  MutterUtils mu = new MutterUtils();
  //追加処理
  //追加後データ件数が1件増えていることを確認
  Query query = new Query(Mutter.class.getSimpleName());
  assertEquals(1, DatastoreServiceFactory.getDatastoreService().prepare(
    query).countEntities());
 }
 public void testGetMutterOf() {
  MutterUtils mu = new MutterUtils();
  //追加処理
  //追加後データ件数が1件増えていることを確認
  List<Mutter> mutters = mu.getMutterOf(userName);
  Query query = new Query(Mutter.class.getSimpleName());
  assertEquals(1, DatastoreServiceFactory.getDatastoreService().prepare(
    query).countEntities());
  //追加後のデータを検証
  for (Mutter mutter : mutters) {
   assertEquals("期待した文字列", mutter.getMessage());
  }
 }
}
テストケースを右クリックして「実行」→「JUnitテスト」をクリックしてテストを実行します。やっぱりローカルでテストできると安心ですねぇ。
 
 
0 件のコメント :
コメントを投稿