SAStrutsを勉強してみる (4) - S2JUnit4でテスト -
タイトル通り。まだ(調査が)微妙なんですが、S2Unit4を使ってテストをしてみる
s2junit4.dicon
が必要な模様なのですが、 http://s2container.seasar.org/2.4/ja/S2JUnit4.html に普通に書いてあるのでそのまま抜粋する。ちょっと削ってる
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE components PUBLIC "-//SEASAR//DTD S2Container 2.4//EN"
"http://www.seasar.org/dtd/components24.dtd">
<components namespace="s2junit4">
<component name="context" class="org.seasar.framework.unit.impl.InternalTestContextImpl">
<!-- これをやるとテストデータがそっくりそのまま入れ替わる -->
<!-- 詳しくはhttp://s2container.seasar.org/2.4/ja/S2JUnit4.html#tipsAllReplace -->
<property name="preparationType">@org.seasar.framework.unit.PreparationType@ALL_REPLACE</property>
</component>
<component class="org.seasar.framework.unit.impl.DataAccessorImpl"/>
<component class="org.seasar.framework.unit.impl.ConfigFileIncluderImpl">
<initMethod name="addConfigFile">
<arg>"app.dicon"</arg>
</initMethod>
<initMethod name="addConfigFile">
<arg>context.testClassShortName + ".dicon"</arg>
</initMethod>
</component>
<component class="org.seasar.framework.unit.impl.TestDataPreparerImpl">
<initMethod name="addTestDataXlsPath">
<arg>context.testClassShortName + "_" + context.testMethodName + ".xls"</arg>
</initMethod>
<initMethod name="addTestDataXlsPath">
<arg>context.testClassShortName + ".xls"</arg>
</initMethod>
</component>
</components>
ってな感じで、テストクラス名.xlsもしくはテストクラス名_テストメソッド名.xlsを使えばテストデータをぶち込める模様
SampleTestCase.xls
上で書いたようにテストデータをぶち込めるExcelファイルを作成する
っていう感じで1行目にテーブルのカラム名、それ以降にそれに対応するデータをぶち込む(Date系の場合、列書式を日付にすれば挿入できるらしいですけど未だ成功せず)
また、シート名はテーブル名にしておく(初期時の要らないシートは消しておく)
SampleService.java
package sample.service;
import java.util.List;
import javax.annotation.Resource;
import org.seasar.extension.jdbc.JdbcManager;
import org.seasar.extension.jdbc.OrderByItem;
import org.seasar.extension.jdbc.exception.SEntityExistsException;
import org.seasar.framework.exception.SQLRuntimeException;
import sample.entity.Sample;
public class SampleService {
@Resource
private JdbcManager jdbcManager;
public List<Sample> getSamples() {
OrderByItem order = new OrderByItem("id", OrderByItem.OrderingSpec.DESC);
return jdbcManager.from(Sample.class).orderBy(order).getResultList();
}
public Sample createSample(Sample sample) {
Sample createdSample = null;
try {
int rowUpdate = jdbcManager.insert(sample).execute();
if (rowUpdate > 0) {
createdSample = sample;
}
} catch (SEntityExistsException e) {
e.printStackTrace();
} catch (SQLRuntimeException e) {
e.printStackTrace();
}
return createdSample;
}
}
この2つのメソッドをテストで使うので定義しておく。あくまで例で、前回のS2JDBCな記事がベース(但し、Date系のカラムは修正)
Sample2Action.java
package sample.action;
import java.util.List;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import org.seasar.struts.annotation.Execute;
import sample.entity.Sample;
import sample.service.SampleService;
public class Sample2Action {
@Resource
private HttpServletRequest request;
@Resource
private HttpSession session;
@Resource
private SampleService sampleService;
public List<Sample> samples;
@Execute(validator = false, removeActionForm = true)
public String index() {
System.out.println(
String.format("X-Framework = %s", request.getHeader("X-Framework"))
);
samples = sampleService.getSamples();
session.setAttribute("test", "hoge fuga foobar");
return "index.jsp";
}
}
SampleTestCase.java
import org.junit.Test;
import org.junit.runner.RunWith;
import org.seasar.framework.mock.servlet.MockHttpServletRequest;
import org.seasar.framework.mock.servlet.MockHttpSession;
import org.seasar.framework.unit.Seasar2;
import org.seasar.framework.unit.annotation.TxBehavior;
import org.seasar.framework.unit.annotation.TxBehaviorType;
import sample.action.Sample2Action;
import sample.entity.Sample;
import sample.service.SampleService;
import static org.junit.Assert.*;
@RunWith(Seasar2.class)
public class SampleTestCase {
private MockHttpServletRequest request;
private MockHttpSession session;
private SampleService service;
private Sample2Action action;
@Test
//@TxBehavior(TxBehaviorType.NONE)
public void testAdd() {
Sample sample = new Sample();
sample.data = "test";
// SampleService.createSampleでテーブルにデータを突っ込む
assertNotNull(service.createSample(sample));
// 突っ込んだあとのテーブルのサイズが4であるかチェック
assertSame(service.getSamples().size(), 4);
}
@Test
public void testActionIndex() {
// リクエストヘッダーに値を突っ込む
request.addHeader("X-Framework", "SAStruts (S2JUnit4)");
// アクションメソッドを実行した結果をテスト
assertSame(action.index(), "index.jsp");
// アクションメソッドからぶち込まれたセッションデータをテスト
assertSame(session.getAttribute("test"), "hoge fuga foobar");
}
}
とりあえずフィールドに定義しとけば、S2Containerで注入される模様。んでテスト側でMockHttpServletRequest等を介する事でアクションメソッド実行のリクエストヘッダーなども注入されるっていう感じなのかも
んで、実行すると上で書いたテストデータがテスト前にぶち込まれる事を確認する。
備考1
ドキュメントではs2junit4.diconでjavaee.diconをインクルードしているけど、これだと何やら依存関係の注入でコケる。 http://blog.roundrop.jp/show/21 を参考にjavaee5.diconではなく、app.diconをインクルードする事で解決出来る模様
未解決要件1 (Txなメソッドがついてるとコミットされずにロールバックされる件)
何やらテストメソッドの接尾辞にTxがついてるとコミットされずにロールバックされるらしいが、つけようがつけまいがロールバックされてる模様げ
な感じでちょっとまだ微妙な所が多いので、分かり次第レポートする予定