La unidad de prueba de actualización de contenido de ModalWindow falla mientras la funcionalidad real funciona como se esperaba: ¿qué estoy haciendo mal?
Pregunta
Por lo tanto, pasé un par de horas tratando de " corregir " esto yo mismo y luego buscar en Google como un loco pero no encontré nada que hubiera ayudado, así que ahora estoy aquí.
Básicamente tengo un Panel
personalizado dentro del propio ModalWindow
de Wicket y, como me gusta la prueba de unidades, quiero probarlo. El comportamiento específico aquí es actualizar el contenido de ModalWindow
: en mi código real de donde extraje esto, el manejo de eventos de Ajax en realidad vuelve a cargar cosas nuevas en el panel de contenido, simplemente las eliminé para hacerlo más corto.
Entonces, aquí está el código del Panel
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);
}
});
}
}
y el marcado correspondiente
<wicket:panel>
<form wicket:id="form">
<input type="submit" value="Ajaxy Click" wicket:id="infoSubmit" />
</form>
</wicket:panel>
Tenga en cuenta que cuando se ejecuta en un contenedor de servlets como Tomcat, esto funciona correctamente. ¡Aquí no hay errores funcionales!
Entonces, ¿cuál es el problema? ¡Parece que no puedo obtener la prueba de unidad para que esto funcione! Mi clase de prueba para el panel se ve así
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();
}
}
y aquí está el stacktrace resultante de ejecutar eso
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)
Entonces, ¿cómo puedo / debo arreglar mi prueba de unidad para que pase?
Solución
Voy a ponerme nervioso aquí y decir: Agregue su componente de Panel a una Página para probar ...
AFAIK no puede probar componentes individuales, pero debe configurar una prueba obteniendo una página y haciendo afirmaciones sobre eso ...
Esto es lo que uso para las pruebas:
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");
}
}
¡Corrígeme si me equivoco!
Otros consejos
La " producción " El código mostrado que aparentemente funciona es inconsistente. Sospecho que la variable campaignForm se supone que es el formulario de campo.
Pero creo que el problema de raíz es que la ventana modal en sí no está en ningún lugar adjunta a un componente y, por lo tanto, no se puede representar.
Si en el código real, está adjunto en algún lugar fuera de su componente MyModalWindowPanel, definitivamente también deberá adjuntarlo en algún lugar de la prueba, probablemente al hacer que su prueba se compile en una página de prueba o en un panel de prueba que contenga tanto ventana modal y el componente bajo prueba.
La única vez que obtuve " No se encontró la página " la excepción fue al intentar llamar a getPage () en un constructor de paneles. El constructor se ejecuta antes de que el panel se agregue a una página, por lo que no se encuentra nada ... ¿Tal vez estás haciendo algo así? Tal vez este código funcione en producción, pero ¿sigue arrojando ese error detrás de escena?
Sé que no es lo que estás buscando, pero he encontrado que Selenium es una gran herramienta para prueba de interfaz de usuario web. JUnit es increíble para probar la lógica, pero Selenium es más adecuado para asegurarse de que se muestre lo correcto en su interfaz de usuario. Se ve bien con su interfaz gui y demás, pero funciona muy bien, y si te gusta un poco, puedes acceder fácilmente a la API de scripting.