0

それで、私は最初にこれを自分で「修正」しようと試み、次に狂人のようにグーグルで検索するのに数時間を費やしましたが、助けになるものは何も見つからなかったので、今ここにいます。

基本的に私はPanelWicket独自の習慣を持っていますが、ModalWindow単体テストが好きなので、それをテストしたいと思います。ここでの特定の動作は、ModalWindowのコンテンツを更新することです。これを抽出した実際のコードでは、Ajaxイベント処理が実際に新しいものをコンテンツパネルにリロードします。これを短くするためにそれらを削除しました。

だから、ここに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);
            }
        });
    }
}

および対応するマークアップ

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

Tomcatなどのサーブレットコンテナで実行すると、これは正しく機能することに注意してください。ここには機能上のバグはありません。

では、何が問題なのでしょうか。これが機能するための単体テストを取得できないようです。パネルのテストクラスは次のようになります

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)

では、ユニットテストに合格するように修正するにはどうすればよいですか?

4

3 に答える 3

2

ここで手足に出て、次のように言います。Panelコンポーネントをテスト用のページに追加します。

個々のコンポーネントをテストすることはできませんが、ページを取得してそれに対してアサートを実行することにより、テストを設定する必要があります。

これは私がテストに使用するものです:

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

私が間違っている場合は私を訂正してください!

于 2009-11-27T23:38:51.503 に答える
1

「ページが見つかりません」という例外が発生したのは、パネルコンストラクターでgetPage()を呼び出そうとしたときだけでした。パネルがページに追加される前にコンストラクターが実行されるため、何も見つかりません...おそらくそのようなことをしていますか?おそらくこのコードは本番環境で機能しますが、それでもそのエラーを舞台裏で投げていますか?

それがあなたが探しているものではないことは知っていますが、SeleniumはWebUIをテストするための優れたツールであることがわかりました。JUnitはロジックのテストに最適ですが、SeleniumはUIに正しいものが表示されることを確認するのに適しています。GUIインターフェースなどではひねくれているように見えますが、うまく機能します。少し掘り下げると、スクリプトAPIに簡単にアクセスできます。

于 2009-12-03T23:19:52.267 に答える
1

表面上は機能することが示されている「本番」コードには一貫性がありません。変数campaignFormはフィールドフォームであると思われます。

しかし、根本的な問題は、モーダルウィンドウ自体が実際にはコンポーネントにアタッチされていないため、レンダリングできないことだと思います。

実際のコードで、MyModalWindowPanelコンポーネントの外部にアタッチされている場合は、テストビルドをテストページまたはモーダルウィンドウとモーダルウィンドウの両方を含むテストパネルのいずれかにすることで、テストのどこかにアタッチする必要があります。テスト中のコンポーネント。

于 2009-11-29T13:45:34.893 に答える