2002/1/25 作成
アプリケーションの単体テストを書くときに、よく使われるのがJUnitです。 JUnit単体では、Javaアプリケーションのテストはできますが、 サーバーサイドのテストはできません(Web上でコンテナから呼ばれるので)。
Struts Testcase はJUnitを拡張し、 Struts上でテストすることを可能にしています。 Struts Testcaseでテストを行う方法には、モックテストとコンテナテストの2つあります。 モックの方はダミーのサーブレットコンテナ、ダミーのサーブレットリクエストを使って、 テストする方法。コンテナテストの方は実際にコンテナを起動して、テストをする方法です。 とりあえず、早くて簡単(な気がする)モックテストを試してみました。
少しさわってみまた感想としては、比較的簡単です。 注意点としては、
参考
Webアプリ開発時によくある問題として、 「2度押し」があります。 例えばショッピングサイトで注文決定ボタンを押して、 画面が切り替わる前に、もう1度注文決定を押してしまったら。。。 2重注文はしたくないですね。
Strutsでは、画面をまたぐトランザクションの仕組みとして、 同期トークンの仕組みを提供しています。Actionクラスの以下のメソッドを使います。
メソッド | 説明 |
---|---|
Action#saveToken(HttpServletRequest) | トークンを作成し保存する |
Action#isTokenValid(HttpServletRequest) | トークンを検証する |
Action#resetTokan(HttpServletRequest) | トークンをクリアする |
以下は同期トークンを使った簡単なシナリオです。 注文決定前の確認画面を表示するActionを想像してください。
上記の太字の部分をActionに実装するとこんな感じになります。
アクションの例:ユニークな文字列(同期トークン)を作成し、セッションに埋める
public ActionForward execute( ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { //.... //同期トークンを保存 saveToken(request); //... return mapping.findForward("success"); }
JSPの例:同期トークン付のformを生成する
<html:form action="/order"> <input type="submit" value="注文決定"/> </html:form> <!--↓確認用--> <p>token=<%=session.getAttribute(org.apache.struts.action.Action.TRANSACTION_TOKEN_KEY)%>
同期トークンは、 存在すれば自動的にform内にhiddenで埋め込まれるので、特に何か指定する必要はありません。 Action.TRANSACTION_TOKEN_KEYは同期トークンをセッションに埋める定数で、 確認(デバッグ)用の記述です。
アクションの例:リクエストの同期トークンとセッションに保存されている同期トークンを比較する
public ActionForward execute( ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { //... boolean valid = isTokenValid(request, true); System.out.println("Is Token Valid? " + valid); if(valid){ //正常系 }else{ //異常系 } //... }
上の例だと、 重要な処理を2度行わないことは保証されていますが、 例えば2度押しされた場合、何を画面に表示するかが問題になります。 「エラーです」と画面に表示しても、 処理が実行されたのかどうかをユーザーが確認できません。 1回目の正しいリクエストの結果を返すのが一番ですが、 けっこうややこしいことをしないといけない気がします。 (というかいい方法あったら教えてください)
JavaScriptの利用が可能ならば、クライアントでの2度押し防止処理と あわせて利用すれば、大体は大丈夫だと思いますが。。。