Struts 2 JUnit Plugin v2.2.3: Расширение класса тестирования StrutsTestCase;'запрос' является нулевым - PullRequest
1 голос
/ 04 июня 2011

Я пытаюсь использовать плагин Struts2 JUnit (v2.2.3 с Struts2 v2.2.3) и столкнулся с несколькими проблемами.

Я пытался использовать Учебник по плагину Struts2 JUnit в качестве руководства.Первое изменение, которое мне нужно было сделать (не в руководстве), - добавить в свой тестовый класс:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={"classpath*:applicationContext-test.xml"}) 

, поскольку при попытке запустить мой модульный тест я получил ошибку:

SEVERE:   [56:51.239] ********** FATAL ERROR STARTING UP STRUTS-SPRING INTEGRATION **********
Looks like the Spring listener was not configured for your web app! 
Nothing will work until WebApplicationContextUtils returns a valid ApplicationContext.
You might need to add the following to web.xml: 
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
SEVERE:   [56:51.254] Dispatcher initialization failed

Это отличается от учебника - кто-нибудь знает, зачем мне это нужно?

Мне также пришлось добавить следующие Spring Jar (у меня есть необходимые файлы Struts2, включенные в мой путь к классам):

  • spring-beans-2.5.6.jar
  • spring-context-2.5.6.jar
  • spring-core-2.5.6.jar
  • spring-test-2.5.6.jar
  • spring-web-2.5.6.jar

Я не использую Spring w / в моем приложении Struts, но я предполагаю,эти банки необходимы для использования объекта mock request и таких в StrutsTestCase.

Мой тестовый класс:

package com.actions;

import java.io.UnsupportedEncodingException;
import java.util.List;

import javax.servlet.ServletException;

import org.apache.log4j.Logger;
import org.apache.struts2.StrutsTestCase;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import com.beans.LabelValueBean;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={"classpath*:applicationContext-test.xml"}) 
public class DocumentCategoryTest extends StrutsTestCase {

    private static Logger log = Logger.getLogger(DocumentCategoryTest .class);

    /**
     * Testing RetrieveDocumentTypesForDocumentCategory
     * Expecting the List<LabelValueBean> is not null
     * @throws ServletException 
     * @throws UnsupportedEncodingException 
     */
    @Test
    public void testRetrieveDocumentTypesForDocumentCategory() throws UnsupportedEncodingException, ServletException {

        final String docCategory = "Employment";

        //set parameters
        request.setParameter("documentCategoryDescription", docCategory);   

        //execute the action
        executeAction("/recipient/RetrieveDocumentTypesForDocumentCategory.action");  

        //retrieve the document types
        @SuppressWarnings("unchecked")
        List<LabelValueBean> testDocTypeList = (List<LabelValueBean>) findValueAfterExecute("documentTypes");

        //make sure the document type list is not null and has at least one document type
        assertNotNull(testDocTypeList);
        assertTrue("At least one document type should exist for category 'Employment'", testDocTypeList.size() > 0);

        //print types
        log.debug("Document types for category '" + docCategory + "'");
        log.debug(testDocTypeList);
    }
}          

Когда я выполняю действие, я получаю NullPointerException на request.setParameter фрагменте кода:

java.lang.NullPointerException
at com.actions.DocumentCategoryTest.testRetrieveDocumentTypesForDocumentCategory(DocumentCategoryTest.java:38)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.springframework.test.context.junit4.SpringTestMethod.invoke(SpringTestMethod.java:160)
at org.springframework.test.context.junit4.SpringMethodRoadie.runTestMethod(SpringMethodRoadie.java:233)
at org.springframework.test.context.junit4.SpringMethodRoadie$RunBeforesThenTestThenAfters.run(SpringMethodRoadie.java:333)
at org.springframework.test.context.junit4.SpringMethodRoadie.runWithRepetitions(SpringMethodRoadie.java:217)
at org.springframework.test.context.junit4.SpringMethodRoadie.runTest(SpringMethodRoadie.java:197)
at org.springframework.test.context.junit4.SpringMethodRoadie.run(SpringMethodRoadie.java:143)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.invokeTestMethod(SpringJUnit4ClassRunner.java:160)
at org.junit.internal.runners.JUnit4ClassRunner.runMethods(JUnit4ClassRunner.java:51)
at org.junit.internal.runners.JUnit4ClassRunner$1.run(JUnit4ClassRunner.java:44)
at org.junit.internal.runners.ClassRoadie.runUnprotected(ClassRoadie.java:27)
at org.junit.internal.runners.ClassRoadie.runProtected(ClassRoadie.java:37)
at org.junit.internal.runners.JUnit4ClassRunner.run(JUnit4ClassRunner.java:42)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:97)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:49)
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)

Это потому, что по какой-то причине request равно нулю в StrutsTestCase.Почему это?Я делаю именно так, как диктует учебник!

Мой класс действий расширяет другой класс (BaseAction), который расширяет ActionSupport и реализует SessionAware.

package com.actions;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;

import com.actions.BaseAction;

/**
 * Retrieves the document types for the passed in document category
 */
public class DocumentIndexingData extends BaseAction {

    private static final long serialVersionUID = 1L;    
    private static Logger log = Logger.getLogger(DocumentIndexingData.class);

    /*=========================================================================
     * FIELDS
     *=========================================================================*/
    /**
     * The description to use to look up the document types for that category
     */
    private String documentCategoryDescription;
    /**
     * List of document types for a category
     */
    private List<LabelValueBean> documentTypes;

    /*=========================================================================
     * PUBLIC METHODS
     *=========================================================================*/
    /**
     * Retrieves & sets list of document types for document category with passed in ID
     * 
     * @return If there is an error, document type will be set to ERROR; SUCCESS is always returned by this method
     */
    public String retrieveDocumentTypesForDocumentCategory() {      

        List<LabelValueBean> docTypes = new ArrayList<LabelValueBean>();

        //retrieve document types for passed in category ID
        log.debug("looking up document types for category: " + getDocumentCategoryDescription());   

                ////////////////
        //retrieve the document types for the document category here...
                ////////////////

        this.setDocumentTypes(docTypes);

        log.debug("document types found: " + getDocumentTypes());

        return SUCCESS;
    }

    /*=========================================================================
     * GETTERS/SETTERS
     *=========================================================================*/
    /**
     * Retrieves the list of document types
     * 
     * @return  list of document types
     */
    public List<LabelValueBean> getDocumentTypes() {
        return documentTypes;
    }
    /**
     * Sets the list of document types
     * 
     * @param documentTypes
     */
    public void setDocumentTypes(List<LabelValueBean> documentTypes) {
        this.documentTypes = documentTypes;
    }
    /**
     * Retrieves the document category to retrieve document types for
     * 
     * @return  the document category
     */
    public String getDocumentCategoryDescription() {
        return documentCategoryDescription;
    }
    /**
     * Sets the document category to retrieve document types for 
     * 
     * @param documentCategoryDescription   the document category to retrieve document types for 
     */
    public void setDocumentCategoryDescription(String documentCategoryDescription) {
        this.documentCategoryDescription = documentCategoryDescription;
    }
}

struts.xmlзапись:

<!-- indexing attributes action -->
<action name="RetrieveDocumentTypesForDocumentCategory" class="com.actions.DocumentIndexingData" method="retrieveDocumentTypesForDocumentCategory">
    <result type="json">
        <param name="root">documentTypes</param>
    </result>
</action>

Я очень внимательно слежу за учебником, почему request null?Большое спасибо за любую помощь!

ОБНОВЛЕНИЕ (Мое решение! Через @Alex): Теперь у меня есть только следующие JAR-файлы Struts, включенные в мой путь к классам:

  • struts2-junit-plugin-2.2.3.jar
  • spring-beans-2.5.6.jar
  • spring-context-2.5.6.jar
  • spring-core-2.5.6.jar
  • spring-test-2.5.6.jar
  • spring-web-2.5.6.jar

Образец теста:

    public class MyTest extends StrutsTestCase {  

        @Test
        public void testMyAction() throws Exception {  

            request.setParameter("aParameter", "aValue");

            //create action proxy
            ActionProxy proxy = getActionProxy("/test/MyAction");
            assertNotNull(proxy);       
            MyAction action = (MyAction) proxy.getAction();
            assertNotNull(action);

            //execute the action
            String result = proxy.execute();

            //make assertions, expecting success and no error messags   
            assertTrue("There should be no field errors: " + action.getFieldErrors(), action.getFieldErrors().size() == 0);
            assertTrue("There should be no action errors: " + action.getActionErrors(), action.getActionErrors().size() == 0);
            assertEquals("Result did not match expected value; ", Action.SUCCESS, result);
        } 
    } 

1 Ответ

3 голосов
/ 06 июня 2011

Я не использую Spring w / в моем приложении Struts, но я предполагаю, что эти jar-файлы необходимы для использования объекта запроса mock и т.п. в StrutsTestCase.

Учитывая сообщения об исключенияхВы видите выше, ваше приложение считает, что оно использует Spring.У вас есть Struts2-Spring-Plugin на вашем пути к классам?Если вы не используете Spring для IoC, вы не должны включать его в свой путь к классам.

Вы должны быть в состоянии проверить свои действия, следуя инструкциям, на которые вы ссылаетесь, без каких-либо пружинных банок, если вы этого не сделаетеиспользуй весну.Попробуйте удалить все пружинные банки и банку с прутиками struts2-spring-plugin.Вам также, конечно, не нужно:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={"classpath*:applicationContext-test.xml"})

в вашем тестовом классе, если вы не используете spring.

Также убедитесь, что ваш файл struts.xml не содержит эту строку:

<constant name="struts.objectFactory" value="org.apache.struts2.spring.StrutsSpringObjectFactory"/>

...