2009-11-26 2 views
0

그래서 저는 처음으로 두 시간을 "수정"하고 광인처럼 인터넷 검색을 시도했지만 도움이 될만한 것을 찾지 못했습니다. 지금 여기 있습니다.유닛 테스트 ModalWindow의 컨텐츠 새로 고침이 실패합니다. 실제 기능이 예상대로 작동하지만 - 내가 뭘 잘못하고 있니?

기본적으로 Wicket 자신의 ModalWindow에 사용자 정의 Panel이 있습니다. 단위 테스트가 좋기 때문에 테스트하고 싶습니다. 여기서 특정 동작은 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) 

그래서, 방법/내 단위 테스트를 수정해야 할 수있는 실행의 결과 스택 트레이스입니까?

+0

긴 제목 (* 더 짧고 짧은 *에 응축하지 않는 한)과 긴 코드 샘플을 미리 알려 주어서 죄송합니다. – Esko

답변

2

여기 사지에 나가서 말할거야 : 개별 구성 요소를 테스트 할 수는 없지만 얻어서 테스트를 설정해야합니다 AFAIK

.. 테스트를위한 페이지에 패널 구성 요소를 추가 일을 페이지와 그에서 주장 ...

이 내가 테스트에 사용할 것입니다 :

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

내가 틀렸다면 정정 해줘 마십시오!

+0

'WicketTester # startPanel()'은 실제로 주어진 패널을'DummyPanelPage'에'panel'이라는 ID로 추가하여 페이지의 단일 컴포넌트로 테스트 할 수 있도록합니다. 그러나'ModalWindow'의 내용으로'Page'를 사용하려고했지만 그 중 하나도 작동하지 않았습니다. – Esko

+0

아, 죄송합니다. 그 모습을 잃었습니다. modalwindowpanel을 그대로 유지하고 'MyTestPage extends WebPage'에 추가하여 테스트 설정을 둘러 보았습니까? WicketTester(). startPanel은 당신이 나에게 말하고있는 것에서는 효과가없는 것 같습니다. – Tim

+0

시간이 흐르며, 죄송합니다 :) 예, 저도 시도해 보았습니다. – Esko

1

"생산"코드는 외관상으로는 작동하지 않는 것으로 나타났습니다. 변수 campaignForm이 필드 형식으로 추측됩니다.

하지만 근본적인 문제는 모달 윈도우 자체가 실제로 구성 요소에 연결되어 렌더링 할 수 없다는 것입니다.

실제 코드에서 MyModalWindowPanel 구성 요소 외부에 부착 된 경우 확실히 테스트 어딘가에 부착해야합니다. 테스트 페이지 나 테스트 패널을 모두 포함하는 테스트 패널을 만들면됩니다. 모달 윈도우 및 테스트중인 구성 요소.

1

패널 생성자에서 getPage()를 호출 할 때 예외가 발견되었습니다. 패널이 페이지에 추가되기 전에 생성자가 실행되므로 아무 것도 발견되지 않습니다. 아마도 이와 비슷한 일을하고 있습니까? 아마도이 코드는 프로덕션에서 작동하지만 여전히 그 오류를 현장에서 던지고 있습니까?

나는 그것이 당신이 찾고있는 것이 아니라는 것을 알고 있지만 Selenium은 웹 UI를 테스트하기위한 훌륭한 도구라고 발견했습니다. JUnit은 로직 테스트에 이상적이지만 Selenium은 UI에 올바른 것을 표시하는 데 더 적합합니다. 그것 gui 인터페이스와 같은 hinky 보이지만 그것은 위대한 작품, 그리고 조금 파고 있다면 스크립트 API를 쉽게 액세스 할 수 있습니다.

+0

그게 내 초기 반응이었고 여기서 문제가되지 않았 음을 확인했습니다. 나는 ModalWindow 내부 구조가 그렇게할지 모르지만, 나는 다음 단계를 점검해야 할 것이라고 생각한다. – Esko