Unit-Tests ModalWindow Inhalt refresh ausfällt, während die eigentliche Funktionalität funktioniert wie erwartet - was mache ich falsch?
Frage
Also, ich habe ein paar Stunden damit verbracht, zuerst diese selbst zu „reparieren“ und dann wie ein Verrückter googeln, aber nichts gefunden, das so jetzt geholfen habe ich bin hier.
Im Prinzip habe ich ein benutzerdefinierte Panel
innerhalb Wicket eigenen ModalWindow
und da ich Unit-Tests mag, mag ich es testen. Das spezifische Verhalten hier ist die ModalWindow
Inhalt erfrischend. In meinem eigentlichen Code aus, wo ich extrahierte dies der Fall Ajax Umgang tatsächlich neue Sachen Content-Panel neu geladen, ich die, die gerade entfernt diesen kürzer machen
So, hier ist der Panel
des Code
package wicket.components;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.ajax.markup.html.form.AjaxButton;
import org.apache.wicket.extensions.ajax.markup.html.modal.ModalWindow;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.markup.html.panel.Panel;
import org.apache.wicket.model.*;
public class MyModalWindowPanel extends Panel {
private Form form;
private ModalWindow modal;
public MyModalWindowPanel(String id, ModalWindow modal) {
super(id);
this.setOutputMarkupId(true);
this.modal = modal;
initializeForm();
addBasicDataFieldsToForm();
add(campaignForm);
}
private void initializeForm() {
form = new Form("form");
form.setOutputMarkupId(true);
}
private void addBasicDataFieldsToForm() {
campaignForm.add(new AjaxButton("infoSubmit",
new Model<String>("Ajaxy Click")) {
protected void onSubmit(AjaxRequestTarget target, Form<?> form) {
modal.setContent(new MyModalWindowPanel(modal.getContentId(),
modal));
modal.show(target);
}
});
}
}
und das entsprechende Markup
<wicket:panel>
<form wicket:id="form">
<input type="submit" value="Ajaxy Click" wicket:id="infoSubmit" />
</form>
</wicket:panel>
Sie beachten, dass, wenn in Servlet-Container wie Tomcat laufen, dies richtig funktioniert - es gibt keine funktionellen Bugs hier
!Also, was ist dann das Problem? Ich bin nicht scheinbar in der Lage, die Unit-Test für diese Arbeit zu bekommen! Meine Testklasse für das Panel wie folgt aussieht
package wicket.components;
import org.apache.wicket.extensions.ajax.markup.html.modal.ModalWindow;
import org.apache.wicket.markup.html.panel.Panel;
import org.apache.wicket.util.tester.*;
import junit.framework.TestCase;
public class MyModalWindowPanelTestCase extends TestCase {
private WicketTester tester;
private ModalWindow modal;
@Override
protected void setUp() throws Exception {
tester = new WicketTester();
modal = new ModalWindow("modal");
tester.startPanel(new TestPanelSource() {
public Panel getTestPanel(String id) {
return new MyModalWindowPanel(id, modal);
}
});
}
public void testReloadingPanelWorks() throws Exception {
// the next line fails!
tester.executeAjaxEvent("panel:campaignForm:campaignInfoSubmit",
"onclick");
tester.assertNoErrorMessage();
}
}
und hier ist die resultierende stacktrace laufen, dass
java.lang.IllegalStateException: No Page found for component [MarkupContainer [Component id = modal]]
at org.apache.wicket.Component.getPage(Component.java:1763)
at org.apache.wicket.RequestCycle.urlFor(RequestCycle.java:872)
at org.apache.wicket.Component.urlFor(Component.java:3295)
at org.apache.wicket.behavior.AbstractAjaxBehavior.getCallbackUrl(AbstractAjaxBehavior.java:124)
at org.apache.wicket.ajax.AbstractDefaultAjaxBehavior.getCallbackScript(AbstractDefaultAjaxBehavior.java:118)
at org.apache.wicket.ajax.AbstractDefaultAjaxBehavior.getCallbackScript(AbstractDefaultAjaxBehavior.java:106)
at org.apache.wicket.extensions.ajax.markup.html.modal.ModalWindow$WindowClosedBehavior.getCallbackScript(ModalWindow.java:927)
at org.apache.wicket.extensions.ajax.markup.html.modal.ModalWindow.getWindowOpenJavascript(ModalWindow.java:1087)
at org.apache.wicket.extensions.ajax.markup.html.modal.ModalWindow.show(ModalWindow.java:352)
at wicket.components.MyModalWindowPanel$1.onSubmit(MyModalWindowPanel.java:45)
at org.apache.wicket.ajax.markup.html.form.AjaxButton$1.onSubmit(AjaxButton.java:102)
at org.apache.wicket.ajax.form.AjaxFormSubmitBehavior.onEvent(AjaxFormSubmitBehavior.java:143)
at org.apache.wicket.ajax.AjaxEventBehavior.respond(AjaxEventBehavior.java:177)
at org.apache.wicket.ajax.AbstractDefaultAjaxBehavior.onRequest(AbstractDefaultAjaxBehavior.java:299)
at org.apache.wicket.util.tester.BaseWicketTester.executeAjaxEvent(BaseWicketTester.java:1236)
at org.apache.wicket.util.tester.BaseWicketTester.executeAjaxEvent(BaseWicketTester.java:1109)
at wicket.components.MyModalWindowPanelTestCase.testReloadingPanelWorks(MyModalWindowPanelPanelTestCase.java:31)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at junit.framework.TestCase.runTest(TestCase.java:168)
at junit.framework.TestCase.runBare(TestCase.java:134)
at junit.framework.TestResult$1.protect(TestResult.java:110)
at junit.framework.TestResult.runProtected(TestResult.java:128)
at junit.framework.TestResult.run(TestResult.java:113)
at junit.framework.TestCase.run(TestCase.java:124)
at junit.framework.TestSuite.runTest(TestSuite.java:232)
at junit.framework.TestSuite.run(TestSuite.java:227)
at org.junit.internal.runners.JUnit38ClassRunner.run(JUnit38ClassRunner.java:81)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:46)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
So Wie kann / soll ich meinen Unit-Test zu beheben, so dass es würde passieren?
Lösung
Ich werde hier auf einem Bein gehen und sagen: Fügen Sie Ihre Panel-Komponente auf eine Seite zum Testen ..
AFAIK Sie nicht einzelne Komponenten testen, sollte aber einen Test, indem sie eine Seite und tun behauptet auf, dass einrichten ..
Dies ist, was ich für den Test verwendet werden:
public class TestHomePage {
private static WicketTester tester;
@BeforeClass
public static void setUp() {
tester = new WicketTester(new WicketApplication() {
@Override
protected void init() {
//Override init to use SpringUtil's SpringContext due to missing WebApplicationContext
addComponentInstantiationListener(new SpringComponentInjector(this, SpringUtil.getContext()));
}
});
}
@Test
public void testRenderMyPage() {
//start and render the test page
tester.startPage(HomePage.class);
//assert rendered page class
tester.assertRenderedPage(HomePage.class);
//assert page contents
tester.assertContains("Welcome to my webpage");
}
}
Bitte korrigiert mich, wenn ich falsch!
Andere Tipps
Die „Produktion“ Code gezeigt, dass angeblich funktioniert inkonsistent. Ich vermute, dass die Variable campaignForm soll die Feldform.
Aber ich denke, das eigentliche Problem ist, dass das modale Fenster selbst nirgends tatsächlich an ein Bauteil angebracht ist und somit nicht wiedergegeben werden kann.
Wenn in dem realen Code, es irgendwo außerhalb Ihrer MyModalWindowPanel Komponente angebracht ist, müssen Sie es auf jeden Fall im Test irgendwo befestigen und, wahrscheinlich, indem sie Ihr Test baut entweder eine Testseite oder ein Testpanel, die beide enthalten die modale Fenster und die zu testende Komponente.
Das einzige Mal, dass ich das „No Seite gefunden“ bekommen habe Ausnahme wurde bei dem Versuch, getPage () in einem Panel Konstruktor aufzurufen. Der Konstruktor ausgeführt wird, bevor die Platte zu einer Seite hinzugefügt wird, so wird nichts gefunden ... Bist du vielleicht so etwas tun? Vielleicht ist dieser Code in der Produktion arbeitet, aber immer noch ist, dass Fehler hinter den Kulissen werfen?
Ich weiß, es ist nicht das, was Sie suchen, aber ich habe festgestellt, Selen ein großes Werkzeug zu sein, Testen von Web-UI. JUnit ist genial für die Test-Logik, aber Selen ist besser geeignet für die Herstellung, das Richtige Displays in Ihrer Benutzeroberfläche sicher. Es sieht hinky damit GUI-Schnittstelle und so, aber es funktioniert gut, und wenn Sie ein wenig das Scripting api graben leicht zugänglich ist.