Feature Requests item #1287539, was opened at 2005-09-11 15:06
Message generated for change (Tracker Item Submitted) made by Item Submitter
You can respond by visiting:
https://sourceforge.net/tracker/?func=detail&atid=684978&aid=1287539&group_id=119783
Please note that this message will contain a full copy of the comment thread,
including the initial issue submission, for this request,
not just the latest update.
Category: core
Group: 1.2
Status: Open
Priority: 5
Submitted By: Ingram Chen (ingramchen)
Assigned to: Nobody/Anonymous (nobody)
Summary: Enhanced MockWebApplication For Testing Controller Logic
Initial Comment:
I have written a WicketTester, which extends
MockWebApplication, to help testing WebPage without the
container. WicketTester is mainly used for tesing
controller
logic and form validation.
the usage of WicketTester will look like:
======================================
(1) case 1: testing WebPage with default constructor
// production code:
public class ManageBook extends WebPage {
public ManageBook() {
add(new Link("toCreate") {
protected void onClick() {
setResponsePage(CreateBook.class);
}
}) ;
}
}
// test code:
public void testLinkCreateBook() {
WicketTester tester = new WicketTester();
//open the test page
tester.start(ManageBook.class);
//do controller logic, such as click/forward
tester.clickLink("toCreate");
// assert correctly forward/redirect.
tester.assertRenderedPage(CreateBook.class);
}
(2) case 2: testing WebPage that has custom constructor
// production code:
public class ViewBook extends WebPage {
public ViewBook(Book book) {
add(new Label("id", book.getId()) ;
add(new Label("name", book.getName()) ;
}
}
// test code:
public void testViewBook() {
WicketTester tester = new WicketTester();
//for WebPage without default consturctor, I
//define a TestPageSource to let the page
//be instatiated lately.
tester.start(new TestPageSource() {
public WebPage getTestPage() {
Book mockBook = new Book("xxId","xxName");
return new ViewBook(mockBook);
}
});
// assertion
tester.assertRenderedPage(ViewBook.class);
tester.assertLabel("id", "xxId" );
tester.assertLabel("name", "xxName" );
}
(3) case 3: testing with Form validaiton and submission:
// production code:
public class CreateBook extends WebPage {
public CreateBook() {
add(new CreateForm("createForm") );
}
// a form with simple validation
public static class CreateForm extends Form {
public CreateForm(String id....) {
super(id, .....) ;
add(new RequiredTextField("id" ) ;
add(new RequiredTextField("name" ) ;
}
//submit and leave a message on next page.
protected void onSubmit() {
//write into db....
SuccessPage page = new SuccessPage();
page.info("book created") ;
setResponePage(page) ;
//expire old page to prevent user re-submit:
getSession().remove(getPage());
}
}
}
//Test code:
public void testCreateBook_validateFail() {
WicketTester tester = new WicketTester();
tester.start(CreateBook.class);
//submit directly without any input:
tester.submitForm("createForm");
tester.assertRenderedPage(CreateBook.class);
//assert error message from validation
tester.assertErrorMessages("id is required"
, "name is required");
}
public void testCreateBook_validatePass() {
WicketTester tester = new WicketTester();
tester.start(CreateBook.class);
//create a FormTester for specific Form
//in current rendered page.
FormTester createFormTester = tester
.prepareFormTester("createForm");
//simulate user input in FormComponent:
createFormTester.setValue("id", "xxId");
createFormTester.setValue("name", "xxName");
//submit the form:
createFormTester.submit();
tester.assertRenderedPage(SuccessPage.class);
//assert info message present.
tester.assertInfoMessages("book created");
//assert previous page expired.
tester.assertExpirePreviousPage();
}
=====================================
The attachements are the implementation I use.
To archive above features, However, I do some hacks
because limitation on MockWebApplicaion...
(1) processRequestCycle() always process request twice,
I can't figure out why this is necessary (because
of redirect ?) and this makes testing controller logic
difficult. I write another processRequestCycleOnce()
instead.
(2) When production code raises exception, requestCycle
will
redirect to ExceptionErrorPage with exception
stacktrace.
Sometimes this makes testcase pass silently. It
would be
helpful that one can obtain RootCause Exception in
ExceptionErrorPage:
public class ExceptionErrorPage extends WebPage {
private transient Throwable rootCause ;
public Throwable getRootCause() {
return rootCause ;
}
}
With this, we can stop the testCase and prompt
with useful assetion message.
(currently I parse the "exception" message in
ExceptionErrorPage manually...)
(3) One may configure a global resource file for whole
application:
MyWebApplication.java
MyWebApplication.properties
but the MockWebApplication.java doesn't seek
MyWebApplication.properties, and this makes
the component that refering global resource fail
in testing.
It would be helpful that one can configure
MockWebApplication.java to refer
MyWebApplication.properties.
(currently I do manually copy...)
(4) add a method in Session to veriy whether the page is
in the PageMap:
boolean Session.contain(Page page)
with this, one can verify
getSession().remove(getPage())
work or not.
(currently I use reflection to direct access
MostRecentlyUsedMap... very bad idea...)
In short, providing above features is sufficient. For
the long term, I hope there will be an offical
WicketTester
or WicketTestCase that with more correct implementation.
----------------------------------------------------------------------
You can respond by visiting:
https://sourceforge.net/tracker/?func=detail&atid=684978&aid=1287539&group_id=119783
-------------------------------------------------------
SF.Net email is Sponsored by the Better Software Conference & EXPO
September 19-22, 2005 * San Francisco, CA * Development Lifecycle Practices
Agile & Plan-Driven Development * Managing Projects & Teams * Testing & QA
Security * Process Improvement & Measurement * http://www.sqe.com/bsce5sf
_______________________________________________
Wicket-develop mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/wicket-develop