2011年6月28日火曜日

Google App Engine for Java のデータストアAPIのテストを実装してみる(その16)

前回までに修正した、サンプルコードを掲載します。

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import com.google.appengine.api.datastore.DatastoreService;
import com.google.appengine.api.datastore.DatastoreServiceFactory;
import com.google.appengine.api.datastore.Entity;
import com.google.appengine.api.datastore.FetchOptions;
import com.google.appengine.api.datastore.Key;
import com.google.appengine.api.datastore.PreparedQuery;
import com.google.appengine.api.datastore.Query;
import com.google.appengine.api.datastore.Query.FilterOperator;
import com.google.appengine.tools.development.testing.LocalDatastoreServiceTestConfig;
import com.google.appengine.tools.development.testing.LocalServiceTestHelper;

/**
 * Google App Engine for Javaにおけるユニットテストのサンプルコード。
 */
public class LocalUnitTestSample {

 private static final String DATA_KIND = "sampleDataKind";

 private LocalServiceTestHelper helper = new LocalServiceTestHelper(new LocalDatastoreServiceTestConfig());

 //private String[] propertyNames = {"pName1","pName2","pName3","pName4","pName5"};
 private String propertyName = "propertyName";

 private String[] propertyValues = {"pValue1","pValue2","pValue3","pValue4","pValue5"};

 private DatastoreService ds;

 private List keyList;

 /**
  * @throws java.lang.Exception
  */
 @Before
 public void setUp() throws Exception {
  helper.setUp();

  //サンプルデータをデータストアに保存する
  putSampleData();
 }

 /**
  * サンプルデータをデータストアに保存するメソッド。
  */
 private void putSampleData() {
  keyList = new ArrayList();
  ds = DatastoreServiceFactory.getDatastoreService();
  for (int i = 0; i < propertyValues.length; i++) {
   Entity entity = new Entity(DATA_KIND);
   entity.setProperty(propertyName, propertyValues[i]);
   Key key = ds.put(entity);
   keyList.add(key);
  }
 }

 /**
  * @throws java.lang.Exception
  */
 @After
 public void tearDown() throws Exception {
  //サンプルデータをデータストアから削除する
  deleteSampleData();

  helper.tearDown();
 }

 /**
  * サンプルデータをデータストアから削除するメソッド。
  */
 private void deleteSampleData() {
  Iterator iter = keyList.iterator();
  while (iter.hasNext()){
   ds.delete(iter.next());
  }
 }

 @Test
 public void doTest(){
  //サンプルデータをデータストアから検索する
  for (int i = 0;i < propertyValues.length;i++){
   Query query = new Query(DATA_KIND);
   query.addFilter(propertyName, FilterOperator.EQUAL, propertyValues[i]);
   PreparedQuery prepare = ds.prepare(query);
   List entitiesList = prepare.asList(FetchOptions.Builder.withDefaults());
   assertEquals(1,entitiesList.size());
   Iterator iter = entitiesList.iterator();
   while (iter.hasNext()){
    Entity entity = iter.next();
    assertTrue(propertyValues[i].equals(entity.getProperty(propertyName)));
   }
  }
 }

}




インストール不要・無料のKaede翻訳ツール:
http://kaedetrans.appspot.com/

2011年6月27日月曜日

Google App Engine for Java のデータストアAPIのテストを実装してみる(その15)

サンプルコードの変更の続きです。


前回の変更で、
putSampleData()メソッドを修正しました。

今回は、
doTest()メソッドの修正です。

まず最初、for文です。
for (int i = 0;i < propertyNames.length;i++){
この行のpropertyNamesの部分がコンパイルエラーになりますので、
propertyValues


と変更します。
ループ条件を構成する配列を、propertyNamesからpropertyValuesにすることで、
プロパティの「値」の数だけ繰り返します。

その次は、
query.addFilter(propertyNames[i], FilterOperator.EQUAL, propertyValues[i]);
の行のうち、propertyNames[i]の部分がコンパイルエラーになるので、
ここに正しいプロパティ名にあたる文字列を入れます。
propertyName
です。
変更後のコードは、
query.addFilter(propertyName, FilterOperator.EQUAL, propertyValues[i])
です。

もう一つは、
whileループ内部のassertTrue()の引数です。
assertTrue(propertyValues[i].equals(entity.getProperty(propertyNames[i])));
この行のpropertyNames[i]を、propertyNameにします。
assertTrue(propertyValues[i].equals(entity.getProperty(propertyName)));
となります。



インストール不要・無料のKaede翻訳ツール
http://kaedetrans.appspot.com/

2011年6月23日木曜日

Google App Engine for Java のデータストアAPIのテストを実装してみる(その14)

サンプルコードの変更の続きです。

前回の変更で、
フィールドpropertyNamesを削除して、
新たにフィールドpropertyNameを作成しました。

すると、コンパイルエラーとなりますので、
エラー部分を修正します。

まず、
putSampleData()メソッドです。

for (int i = 0;i < propertyNames.length;i++){

の行を、
for (int i = 0;i < propertyValues.length;i++){

と変更します。
propertyNamesをpropertyValuesとするわけです。

次に、
entity.setProperty(propertyNames[i],propertyValues[i]);


の行を
entity.setProperty(propertyName,propertyValues[i]);

とします。
propertyNames[i]をpropertyNameに変更しています。

次回は、doTest()メソッドを変更します。


インストール不要・無料のKaede翻訳ツール
http://kaedetrans.appspot.com/

2011年6月21日火曜日

Google App Engine for Java のデータストアAPIのテストを実装してみる(その13)

サンプルコードの改造を進める前に、
テスト用のサンプルデータを変更します。

と言っても、プロパティ名を変更するだけです。

フィールドpropertyNamesはjava.lang.String配列になっていますが、
String型に変更します。

private String[] propertyNames = 
{"pName1","pName2","pName3","pName4","pName5"};
の行を、
private String propertyName = "propertyName";
と変更します。

次に、
メソッドputSampleData()の実装を変更します。


インストール不要・無料のKaede翻訳ツール
http://kaedetrans.appspot.com/

2011年6月18日土曜日

Google App Engine for Java のデータストアAPIのテストを実装してみる(その12)

今回は、サンプルコードの改変はお休みです。
その代わり、サンプルコード全体の流れを
書いてみます。


このサンプルコードは、
setUp()
putSampleData()
doTest()
tearDown()
deleteSampleData()
の5つのメソッドを実装しています。
この中で、putSampleData()、deleteSampleData()の2つは
それぞれsetUp()、tearDown()の内部で呼び出されるだけなので、
テストを実行する上で、メソッド呼び出しの流れとしては
serUp()
doTest()
tearDown()
という順になります。JUnit4で使用されるアノテーションが付いた
メソッドだけです。

・テストの前準備(サンプルデータの保存)
・テストの実行(サンプルデータの検索)
・テストの後処理(サンプルデータの削除)
単純な流れですね。



インストール不要・無料のKaede翻訳ツール
http://kaedetrans.appspot.com/

2011年6月17日金曜日

Google App Engine for Java のデータストアAPIのテストを実装してみる(その11)

前回は、tearDown()メソッドの中身を変更してみました。
2行だけのメソッドなので、行ごと順番を入れ替えただけです。

すると、NullPointerExceptionがスローされました。
LocalServiceTestHelper.tearDown()の呼び出しの後に
データストアのAPIを呼び出しているためでした。

今回は、tearDown()と対になるメソッドである、
@Beforeアノテーションの付いている
setUp()メソッド
を改造してみます。

その前に、tearDown()メソッドは元に戻しておきましょう。

サンプルコードの変更はこちら。
/**
  * @throws java.lang.Exception
  */
 @Before
 public void setUp() throws Exception {
  //サンプルデータをデータストアに保存する
  putSampleData();

  helper.setUp();

 }

 /**
  * @throws java.lang.Exception
  */
 @After
 public void tearDown() throws Exception {
  //サンプルデータをデータストアから削除する
  deleteSampleData();

  helper.tearDown();
 }


前述の通り、setUp()メソッドの2行を入れ替えただけです。

テストを実行すると、
やはりNullPointerExceptionが
helper.tearDown();
のところでスローされます。

データストアの操作は、
helper.setUp()と
helper.tearDown()
の間で行う必要があるということです。




インストール不要・無料のKaede翻訳ツール
http://kaedetrans.appspot.com/

2011年6月13日月曜日

Google App Engine for Java のデータストアAPIのテストを実装してみる(その10)

データストアAPIのテストでは、
LocalServiceTestHelperの機能を利用して、
データストアへのデータの格納を行っています。

そのために実装する必要があるのは、
・LocalServiceTestHelperのインスタンスの生成
・LocalServiceTestHelper.setUp()の呼び出し
・LocalServiceTestHelper.tearDown()による後処理
となります。

この3つの手順の順番は変更できません。
試しに、
前回まで説明してきたサンプルコードの
tearDown()メソッド内、
deleteSampleData()メソッドと
helper.tearDown()メソッド
の順番を入れ替えてみましょう。

@After
public void tearDown(){
 deleteSampleData();
 helper.tearDown();
}

と変更して、テストを起動してみてください。
すると、
deleteSampleData()の行でNullPointerExceptionがスローされます。
helper.tearDown()が既に呼び出されているためです。




インストール不要・無料のKaede翻訳ツール
http://kaedetrans.appspot.com/

2011年6月11日土曜日

Google App Engine for Java のデータストアAPIのテストを実装してみる(その9)

前回までで、LocalUnitTestSampleクラスについて
説明しました。

JUnit4では、
@Beforeアノテーションの付いたメソッド

@Testアノテーションの付いたテストメソッド

@Afterアノテーションの付いたメソッド
の順番で、各テストメソッドについて順に実行されるのですが、
LocalUnitTestSampleクラスでは、
@BeforeのsetUp()メソッドで、サンプルデータの準備
@TestのdoTest()メソッドで、データストアの検索と検証
@AfterのtearDown()メソッドで、サンプルデータの消去
という流れで処理されます。

この中で、LocalServiceTestHelperクラスの
・setUp()
・tearDown()
のメソッドの使い方について、
次回以降にサンプルコードに少し手を加えながら
実験してみます。



インストール不要・無料のKaede翻訳ツール
http://kaedetrans.appspot.com/

2011年6月9日木曜日

Google App Engine fo Java のデータストアAPIのテストを実装してみる(その8)

前回のdoTest()メソッドの説明の続きです。


List entitiesList = prepare.asList(FetchOptions.Builder.withDefaults());
prepareからjava.util.List形式で検索結果のエンティティを取り出しています。
取り出したエンティティの数が1であることを検証するために
asList()メソッドを使っています。
取得するエンティティの数を限定する必要はないため、
引数はFetchOptions.Builder.withDefaults()です。


assertEquals(1,entitiesList.size());
検索結果のエンティティの数が1であることを検証しています。

Iterator iter = entitiesList.iterator();
取得したエンティティの中身について検証するために、
java.util.Iterator を取得します。

while (iter.hasNext()){
 Entity entity = iter.next();
 assertTrue(propertyValues[i].equals(entity.getProperty(propertyNames[i])));
}
iterに要素が残っている間のループです。
エンティティを取得して、propertyNames[i]の名前のプロパティを取得し、
propertyValues[i]と同じであることを検証しています。



インストール不要・無料のKaede翻訳ツール
http://kaedetrans.appspot.com/

2011年6月7日火曜日

Google App Engine for Java のデータストアAPIのテストを実装してみる(その7)

今回は、テストの実体となる doTest()メソッドの説明を行います。
実のところ、このメソッドの中身はサンプルコードの要点ではないので、
とりあえず実装しているだけです。
サンプルコードは、@Beforeと@Afterの内部の実装について
説明するための実験用です。


@Test
 public void doTest(){
  //サンプルデータをデータストアから検索する
  for (int i = 0;i < propertyNames.length;i++){
   Query query = new Query(DATA_KIND);
   query.addFilter(propertyNames[i], FilterOperator.EQUAL, propertyValues[i]);
   PreparedQuery prepare = ds.prepare(query);
   List entitiesList = prepare.asList(FetchOptions.Builder.withDefaults());
   assertEquals(1,entitiesList.size());
   Iterator iter = entitiesList.iterator();
   while (iter.hasNext()){
    Entity entity = iter.next();
    assertTrue(propertyValues[i].equals(entity.getProperty(propertyNames[i])));
   }
  }
 }

@Testアノテーションの付いている
doTest()メソッドは、実際のテストコードです。

メソッド内で行われている動作は、
  propertyNamesの各要素をプロパティ名として、
  該当するプロパティ値を持つエンティティを検索する
   ↓
  取得したエンティティのプロパティ値を検証する
という内容です。
これをpropertyNamesの長さ分、繰り返しています(forブロック)。

Query query = new Query(DATA_KIND);
この行は、DATA_KINDで取得するデータの種類を指定して
Queryを生成しています。

query.addFilter(propertyNames[i],FilterOperator.Builder.EQUAL,propertyValues[i]);
引数propertyNames[i]は検索するプロパティ名、
引数FilterOperator.Builder.EQUALはプロパティ値の検索条件を同値とすること、
引数propertyValues[i]は、プロパティ値の境界を設定しています。

PreparedQuery prepare = ds.prepare(query);
ds.prepare()メソッドの検索条件を設定したクエリオブジェクトを渡して、
検索の実行を準備します。

この後、クエリを実行してエンティティを取り出しますが、
次回に説明します。



インストール不要・無料のKaede翻訳ツール
http://kaedetrans.appspot.com/

2011年6月5日日曜日

Google App Engine for Java のデータストアAPIのテストを実装してみる(その6)

今回説明するのは、deleteSampleData()メソッドです。

/**
  * サンプルデータをデータストアから削除するメソッド。
  */
 private void deleteSampleData() {
  Iterator iter = keyList.iterator();
  while (iter.hasNext()){
   ds.delete(iter.next());
  }
 }


このメソッドは、
@Afterアノテーションの付けられている
tearDown()メソッド内で呼び出される、
サンプルデータをデータストアから削除するメソッドです。

実際に運用する場合は、このようなメソッドを実装する必要はありません。
helper.tearDown()メソッドでLocalServiceTestHelperの終了処理が行われると、
メモリ上に保存されたデータストアのデータは消去されるからです。

しかし、このサンプルコードでは、その機能を確認するために
実装しています。

それでは、メソッドの中身について説明します。

Iterator. iter = keyList.iterator();
の行は、keyListからKeyを格納したjava.util.Iteratorを取得します。

次のwhileブロックは、取得したiterを使って
キーを指定してデータの削除を行っています(ds.delete(iter.next())の行)。



インストール不要・無料のKaede翻訳ツール
http://kaedetrans.appspot.com/

2011年6月2日木曜日

Google App Engine for Java のデータストアAPIのテストを実装してみる(その5)

今回は、tearDown()メソッドについて説明します。

/**
  * @throws java.lang.Exception
  */
 @After
 public void tearDown() throws Exception {
  //サンプルデータをデータストアから削除する
  deleteSampleData();

  helper.tearDown();
 }

tearDown()メソッドには、
@Afterアノテーションが付いています。

これにより、各テストメソッド(@Testアノテーション)の実行後に
tearDown()メソッドが呼び出されます。

メソッドの中身を見てみましょう。

deleteSampleData()メソッドは(次回以降説明します)、
データストアからサンプルとして保存したデータ(putSampleData()メソッド)を
削除するメソッドです。

helper.tearDown()は、LocalServiceTestHelperが提供する
ローカル環境でのサービスの終了処理を行います。
このメソッドが呼び出された後では、GAEのサービスをローカル環境で
利用することはできません。




インストール不要・無料のKaede翻訳ツール
http://kaedetrans.appspot.com/