代码之家  ›  专栏  ›  技术社区  ›  Esko

单元测试ModalWindow的内容刷新失败,而实际功能按预期工作-我做错了什么?

  •  0
  • Esko  · 技术社区  · 15 年前

    所以,我先花了几个小时试图自己“修复”这个问题,然后像疯子一样在谷歌上搜索,但没有找到任何有帮助的东西,所以现在我在这里。

    基本上我有一个习惯 Panel ModalWindow 因为我喜欢单元测试,所以我想测试它。这里的具体行为是刷新 模态窗口

    所以,下面是答案 用户代码

    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);
                }
            });
        }
    }
    

    以及相应的标记

    <wicket:panel>
        <form wicket:id="form">
            <input type="submit" value="Ajaxy Click" wicket:id="infoSubmit" />
        </form>
    </wicket:panel>
    

    请注意,当在诸如Tomcat之类的servlet容器中运行时,它工作正常-这里没有功能性错误!

    单元测试 为了让它发挥作用!我的面板测试类如下所示

    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();
        }
    }
    

    这是运行该程序的结果跟踪

    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)
    

    所以

    3 回复  |  直到 15 年前
        1
  •  2
  •   Tim    15 年前

    我会在这里说:将面板组件添加到页面以进行测试。。

    这是我用于测试的内容:

    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");
        }
    }
    

    如果我错了,请纠正我!

        2
  •  1
  •   Don Roby    15 年前

    但是我认为根本的问题是模态窗口本身实际上没有连接到组件,因此无法渲染。

    如果在实际代码中,它附加在MyModalWindowPanel组件之外的某个地方,那么您肯定也需要将它附加到测试中的某个地方,很可能是通过使您的测试生成一个测试页面或一个同时包含模式窗口和被测组件的测试面板。

        3
  •  1
  •   Loren_    15 年前

    我唯一一次遇到“找不到页面”异常是在面板构造函数中尝试调用getPage()时。构造函数在面板添加到页面之前执行,因此找不到任何内容。。。你可能在做类似的事情吗?也许这段代码可以在生产环境中使用,但仍然在幕后抛出错误?

    我知道这不是你要找的,但我找到了 Selenium