= 拡張Wicketテスタ =
ここでは、Wicketに標準で備わっている[[wicket/Problems|ひどいテスタ]]の代わりに、タイプセーフでリファクタリングに強い代替のテスタを提案してみる。
== ひどいWicketプログラムとそのテスト ==
ひどいとは言っても、ごく普通に書くとこうなる。
{{{
Login
}}}
{{{
import org.apache.wicket.markup.html.*;
import org.apache.wicket.markup.html.form.*;
import org.apache.wicket.markup.html.panel.*;
import org.apache.wicket.model.*;
public class LoginPage extends WebPage {
public LoginPage() {
add(new FeedbackPanel("feedback"));
add(new LoginForm());
}
class LoginForm extends Form {
private LoginForm() {
super("loginForm");
add(new TextField("email", new Model()));
add(new PasswordTextField("pass", new Model()));
}
@Override
public void onSubmit() {
String mail = get("email").getDefaultModelObjectAsString();
String pass = get("pass").getDefaultModelObjectAsString();
// login success or failed ....
}
}
}
}}}
{{{
import org.apache.wicket.util.tester.*;
import org.junit.*;
public class LoginTest {
@Test
public void test() {
WicketTester tester = new WicketTester();
tester.startPage(LoginPage.class);
tester.assertRenderedPage(LoginPage.class);
tester.assertNoErrorMessage();
FormTester formTester = tester.newFormTester("loginForm");
formTester.setValue("email", "sysdba");
formTester.setValue("pass", "masterkey");
formTester.submit();
tester.assertNoErrorMessage();
}
}
}}}
== LoginPageの改良 ==
少なくともLoginPageクラスは以下のようにし、文字列ではなく文字列定数を参照すべきだろう。
{{{
import org.apache.wicket.markup.html.*;
import org.apache.wicket.markup.html.form.*;
import org.apache.wicket.markup.html.panel.*;
import org.apache.wicket.model.*;
public class LoginPage extends WebPage {
static final String ID_FEEDBACK = "feedback";
static final String ID_LOGINFORM = "loginForm";
static final String ID_EMAIL = "email";
static final String ID_PASS = "pass";
public LoginPage() {
add(new FeedbackPanel(ID_FEEDBACK));
add(new LoginForm());
}
class LoginForm extends Form {
private LoginForm() {
super(ID_LOGINFORM);
add(new TextField(ID_EMAIL, new Model()));
add(new PasswordTextField(ID_PASS, new Model()));
}
@Override
public void onSubmit() {
String mail = get(ID_EMAIL).getDefaultModelObjectAsString();
String pass = get(ID_PASS).getDefaultModelObjectAsString();
// login success or failed ....
}
}
}
}}}
さらにLoginPageTestも以下のように、その文字列定数を参照させる。
{{{
import org.apache.wicket.util.tester.*;
import org.junit.*;
import static test.LoginPage.*;
public class LoginTest {
@Test
public void test() {
WicketTester tester = new WicketTester();
tester.startPage(LoginPage.class);
tester.assertRenderedPage(LoginPage.class);
tester.assertNoErrorMessage();
FormTester formTester = tester.newFormTester(ID_LOGINFORM);
formTester.setValue(ID_EMAIL, "sysdba");
formTester.setValue(ID_PASS, "masterkey");
formTester.submit();
tester.assertNoErrorMessage();
}
}
}}}
== 本当はこのようにしたい ==
LoginPage側では、テストで参照されるであろうコンポーネントをフィールドとして保持しておく。
これは問題ない。
{{{
import org.apache.wicket.markup.html.*;
import org.apache.wicket.markup.html.form.*;
import org.apache.wicket.markup.html.panel.*;
import org.apache.wicket.model.*;
public class LoginPage extends WebPage {
static final String ID_FEEDBACK = "feedback";
static final String ID_LOGINFORM = "loginForm";
static final String ID_EMAIL = "email";
static final String ID_PASS = "pass";
LoginForm loginForm;
public LoginPage() {
add(new FeedbackPanel(ID_FEEDBACK));
add(loginForm = new LoginForm());
}
class LoginForm extends Form {
TextFieldemailField;
PasswordTextField passField;
private LoginForm() {
super(ID_LOGINFORM);
add(emailField = new TextField(ID_EMAIL, new Model()));
add(passField = new PasswordTextField(ID_PASS, new Model()));
}
@Override
public void onSubmit() {
String mail = emailField.getDefaultModelObjectAsString();
String pass = passField.getDefaultModelObjectAsString();
// login success or failed ....
}
}
}
}}}
テストの方は以下のようにしたい。ID文字列は一切使わず、コンポーネントのみを参照する。
これはWicket付属のテスターではできない。
{{{
public class LoginTest {
@Test
public void test() {
WicketTester tester = new WicketTester();
tester.startPage(LoginPage.class);
tester.assertRenderedPage(LoginPage.class);
tester.assertNoErrorMessage();
LoginPage loginPage = tester.getLastRenderedPage();
LoginForm loginForm = loginPage.loginForm;
FormTester formTester = tester.newFormTester(loginForm);
formTester.setValue(loginForm.emailField, "sysdba");
formTester.setValue(loginForm.passField, "masterkey");
formTester.submit();
tester.assertNoErrorMessage();
}
}
}}}
== 拡張Wicketテスタ ==
ということで、[[wicket/ExWicketTester/Source|ソースはこちら]]。
これを使うとテストユニットは次のように書ける。
{{{
import org.junit.*;
import test.LoginPage.*;
import com.cm55.third.wicket.test.*;
public class LoginTest {
@Test
public void test() {
ExWicketTester tester = new ExWicketTester();
LoginPage loginPage = tester.startPage(LoginPage.class);
tester.assertRenderedPage(LoginPage.class);
tester.assertNoErrorMessage();
LoginForm loginForm = loginPage.loginForm;
ExFormTester formTester = tester.newFormTester(loginForm);
formTester.setValue(loginForm.emailField, "sysdba");
formTester.setValue(loginForm.passField, "masterkey");
formTester.submit();
tester.assertNoErrorMessage();
}
}
}}}