2012年3月23日金曜日

WicketTesterで独自のSessionを使用するには

アプリケーションで独自のSessionを使用するには、WebApplication.newSessionをオーバーライドします。
WicketTesterで単体テストをするときも、そのApplicationをコンストラクタに渡せば、そのSessionを使ってテストができます。
しかしこれは単体テストとしては今ひとつ。できればApplicationに依存しないテストを書きたい。Applicationのテストをしたいのではなく、Componentのテストをしたいのだ–。

MockApplicationを使う
何か適当な解決策はないものか、と考えたところで思いついたのが、MockApplicationを継承して使うという方法でした。
MockApplicationはWicketTesterのデフォルトコンストラクタが呼ばれたときに使用されるApplicationのため、もっともシンプルな解決策ではないかと考えました。
というわけで、MockApplication.newSessionをオーバーライドすれば独自のSessionが使えることを確認する試験を書きました。WicketTesterを起動した後、Sessionを取得して型を検査しています。

import org.apache.wicket.Session;
import org.apache.wicket.mock.MockApplication;
import org.apache.wicket.protocol.http.WebApplication;
import org.apache.wicket.protocol.http.WebSession;
import org.apache.wicket.request.Request;
import org.apache.wicket.request.Response;
import org.apache.wicket.util.tester.WicketTester;
import org.junit.Test;
import static org.junit.Assert.*;
public class SetSessionTest {
@Test
public void testSessionCreated() {
WebApplication app = new MockApplication() {
public Session newSession(Request request, Response response) {
return new CustomizedSession(request);
}
};
WicketTester tester = new WicketTester(app);
Session session = Session.get();
assertTrue(session instanceof CustomizedSession);
}
static class CustomizedSession extends WebSession {
CustomizedSession(Request request) {
super(request);
}
}
}
これでまたTDDの道を極めたぜ。

2012年3月18日日曜日

Javaのtrimについて

Javaで末尾の全角/半角スペースをトリムする
気になったことがあったので僕も実験してみた。
気になったのは、次の2つ。
  1. 正規表現のコンパイルを一回にしたらどれくらい改善できるのか
  2. 末尾から空白を検索した方が早くね?
というわけでメソッドを2つ追加して実験してみた。
結果は、
  1. trim2と同じか少し遅いくらいまで改善
  2. trim3と同じか少し早いくらい
  3. trim1はダントツで遅い
といった感じになりました。String.replaceAllは遅いですけど書きやすいので、問題を把握した上で使いましょう。
import java.util.regex.Pattern;
public class Main {
private static final String VALUE = "あいう    ";
public static void main(String[] args) {
long[] times = new long[6];
times[0] = System.nanoTime();
for(int i = 0; i < 10000; i++) {
trim1(VALUE);
}
times[1] = System.nanoTime();
for(int i = 0; i < 10000; i++) {
trim2(VALUE);
}
times[2] = System.nanoTime();
for(int i = 0; i < 10000; i++) {
trim3(VALUE);
}
times[3] = System.nanoTime();
for(int i = 0; i < 10000; i++) {
trim4(VALUE);
}
times[4] = System.nanoTime();
for(int i = 0; i < 10000; i++) {
trim5(VALUE);
}
times[5] = System.nanoTime();
String fmt = "trim%d: %d";
for(int i = 0; i < 5; i++){
String str = String.format(fmt, i + 1, times[i + 1] - times[i]);
System.out.println(str);
}
}
public static String trim1(String value) {
return value.replaceAll("( | )+\\z", "");
}
public static String trim2(String value) {
StringBuilder sb = new StringBuilder(value);
for(int i = sb.length()-1; 0 <= i; i--) {
char c = sb.charAt(i);
if(c == ' ' || c == ' ') sb.deleteCharAt(i);
else break;
}
return sb.toString();
}
public static String trim3(String value) {
char[] ary = value.toCharArray();
char[] trimed = new char[ary.length];
for(int i = ary.length-1; 0 <= i; i--) {
if(ary[i] == ' ' || ary[i] == ' ') continue;
else trimed[i] = ary[i];
}
return new String(trimed);
}
private static Pattern pattern = Pattern.compile("( | )+\\z");
public static String trim4(String value) {
return pattern.matcher(value).replaceAll("");
}
public static String trim5(String value) {
for(int index = value.length() - 1; 0 <= index; index--){
char chr = value.charAt(index);
if(chr == ' ' || chr == ' '){
continue;
}
return value.substring(0, index + 1);
}
return value;
}
}
view raw Main.java hosted with ❤ by GitHub

2012年3月8日木曜日

Code Year 2012 - Week 8

今週は2回目のブラックジャックゲーム。
行数が多いので見にくい。JavaScriptにはJavaのimportにあたるような機能はないのかな?

2012年3月3日土曜日

Code Year 2012 - Week 7

今週の課題はループ。
forとwhileだけじゃなく、再帰を使ったループもあった。
再帰は普段使わないからけっこう手間取った。
8週目の課題がこなかったのはもたもたしてたからかな?