Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/spring-mvc/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Unit testing Spring3.1依赖注入-JUnit测试_Unit Testing_Spring Mvc_Controller_Nullpointerexception - Fatal编程技术网

Unit testing Spring3.1依赖注入-JUnit测试

Unit testing Spring3.1依赖注入-JUnit测试,unit-testing,spring-mvc,controller,nullpointerexception,Unit Testing,Spring Mvc,Controller,Nullpointerexception,我正在使用SpringMVC3.1,并尝试测试一个名为LoginController的控制器类。当authenticate方法尝试使用引用authenticationService进行调用时,我在authenticate方法中得到一个空指针异常,该引用authenticationService在LoginController类中自动连接。我也提到了这一点。请参阅下面的代码以了解更多信息 LoginControllerTest.java @RunWith(SpringJUnit4ClassRun

我正在使用SpringMVC3.1,并尝试测试一个名为LoginController的控制器类。当authenticate方法尝试使用引用authenticationService进行调用时,我在authenticate方法中得到一个空指针异常,该引用authenticationService在LoginController类中自动连接。我也提到了这一点。请参阅下面的代码以了解更多信息

LoginControllerTest.java

 @RunWith(SpringJUnit4ClassRunner.class)
 @ContextConfiguration(locations = {"classpath:servlet-context.xml"})
public class LoginControllerTest extends DatabaseSupport {

@Autowired
private ApplicationContext applicationContext;

@Autowired
private LoginController loginController;

 @Autowired
private AuthenticationService authenticationService;

private MockHttpServletRequest request;
private MockHttpServletResponse response;
private RequestMappingHandlerAdapter handlerAdapter;

private LoginForm loginForm;


@Before
public void setUp() {
    request = new MockHttpServletRequest();
    response = new MockHttpServletResponse();

    handlerAdapter = applicationContext.getBean(RequestMappingHandlerAdapter.class);
    authenticationService = applicationContext.getAutowireCapableBeanFactory()
                           .createBean(AuthenticationService.class);
    loginController = new LoginController();
    loginForm = new LoginForm();

}


@Test
public void loginTest() throws Exception {
    final String expectedMessage = "login";
    final String requestUri = "/";
    final HandlerMethod expectedHandlerMethod;

    final MockHttpServletRequest request;
    final MockHttpServletResponse response;

    request = new MockHttpServletRequest();
    response = new MockHttpServletResponse();
    request.setMethod("GET");

    request.setRequestURI(requestUri);

    expectedHandlerMethod = new HandlerMethod(loginController, "login");
    ModelAndView mav = handlerAdapter.handle(request, response, expectedHandlerMethod); //this.getHandler(request);


    assertViewName(mav, expectedMessage);
}


@Test
public void logoutTest() throws Exception {
    final String expectedMessage = "login";
    final String requestUri = "/";
    final HandlerMethod expectedHandlerMethod;

    final MockHttpServletRequest request;
    final MockHttpServletResponse response;

    request = new MockHttpServletRequest();
    response = new MockHttpServletResponse();
    request.setMethod("GET");

    request.setRequestURI(requestUri);

    expectedHandlerMethod = new HandlerMethod(loginController, "logout");
    ModelAndView mav = handlerAdapter.handle(request, response, expectedHandlerMethod); //this.getHandler(request);


    assertViewName(mav, expectedMessage);
}


@Test
public void authenticateTest() throws Exception {
    //final String expectedMessage = "redirect:search/";
    final String requestUri = "/";
    final HandlerMethod expectedHandlerMethod;
    final Map mav;

    final MockHttpServletRequest request;
    final MockHttpServletResponse response;

    loginForm.setUserName("abell");
    loginForm.setPassWord("PassW0rd");

    request = new MockHttpServletRequest();
    response = new MockHttpServletResponse();
    request.setMethod("GET");
    request.setRequestURI(requestUri);
    mav = new HashMap();

      //authenticate(@ModelAttribute("loginForm") LoginForm loginForm, Map model, HttpServletRequest request)
    //expectedHandlerMethod = new HandlerMethod(loginController, "authenticate");
    //ModelAndView mav = handlerAdapter.handle(request, response, expectedHandlerMethod); //this.getHandler(request);
    String expectedMessage = loginController.authenticate(loginForm, mav, request);

    assertTrue(expectedMessage.equalsIgnoreCase("redirect:search/"));
}


private Object getHandler(MockHttpServletRequest request) throws Exception {
    HandlerExecutionChain chain = null;

    Map<String, HandlerMapping> map = applicationContext.getBeansOfType(HandlerMapping.class);
    Iterator<HandlerMapping> itt = map.values().iterator();


    while (itt.hasNext()) {
        HandlerMapping mapping = itt.next();
        chain = mapping.getHandler(request);
        if (chain != null) {
            break;
        }
    }

    if (chain == null) {
        throw new InvalidParameterException("Unable to find handler for request URI: " + request.getRequestURI());
    }

    return chain.getHandler();
   }
}
@Controller
@SessionAttributes
@RequestMapping("/")
public class LoginController {

    private static final Logger logger = LoggerFactory.getLogger(LoginController.class);

    @Autowired
    private AuthenticationService authenticationService;

    @Autowired
    private WloanInfoDao wloanInfoDao;

    @Autowired
    private UserProfile userProfile;


    @RequestMapping(value = "/", method = RequestMethod.GET)
    public String login() {

            return "login";
    }

    @RequestMapping(value = "/logout", method = RequestMethod.GET)
    public String logout() {
            logger.info("Logout");
            return "login";

    }

    @RequestMapping(value="/authenticate", method = RequestMethod.POST)
    public String authenticate(@ModelAttribute("loginForm") LoginForm loginForm, Map    model, HttpServletRequest request) throws AuthenticationException {
            try {
                    boolean authenticated = authenticationService.authenticate(loginForm.getUserName(), loginForm.getPassWord());

                    if (authenticated) {
                            userProfile.setUsername(loginForm.getUserName());
                            userProfile.setAuthenticated(true);
                            return "redirect:search/";
                    }

                    model.put("loginForm", loginForm);
                    request.setAttribute("errorMessage","Invalid username or password.");
            } catch (AuthenticationException e) {
                    logger.error("Error occurring during login: " + e.getMessage(), e);
                    throw new AuthenticationException(e);
            }
            return "login";
            }

             }

AuthenticationService.java


servlet context.xml

 <?xml version="1.0" encoding="UTF-8"?>
 <beans xmlns="http://www.springframework.org/schema/beans"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xmlns:p="http://www.springframework.org/schema/p"
   xmlns:context="http://www.springframework.org/schema/context"
   xmlns:mvc="http://www.springframework.org/schema/mvc"
   xmlns:aop="http://www.springframework.org/schema/aop"
   xmlns:tx="http://www.springframework.org/schema/tx"
   xsi:schemaLocation="
   http://www.springframework.org/schema/beans
   http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
   http://www.springframework.org/schema/context
   http://www.springframework.org/schema/context/spring-context-3.0.xsd
   http://www.springframework.org/schema/mvc
   http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
   http://www.springframework.org/schema/aop
   http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
   http://www.springframework.org/schema/tx
   http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">

    <!-- DispatcherServlet Context: defines this servlet's request-processing infrastructure -->

    <!-- Enables the Spring MVC @Controller programming model -->
    <mvc:annotation-driven/>

    <aop:aspectj-autoproxy proxy-target-class="true"/>

    <import resource="hibernate-context.xml"/>

    <!-- Handles HTTP GET requests for /resources/** by efficiently serving up static resources in the ${webappRoot}/resources directory -->
    <mvc:resources mapping="/media/**" location="/media/"/>

    <!-- Resolves views selected for rendering by @Controllers to .jsp resources in the /WEB-INF/views directory -->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
            <property name="prefix" value="/WEB-INF/views/"/>
            <property name="suffix" value=".jsp"/>
    </bean>
    <!-- Spring is retarded, -->
    <bean class="org.springframework.beans.factory.config.CustomScopeConfigurer">
            <property name="scopes">
                    <map>
                            <entry key="session">
                                    <bean class="org.springframework.context.support.SimpleThreadScope"/>
                            </entry>
                    </map>
            </property>
    </bean>

    <bean id="multipartResolver"
          class="org.springframework.web.multipart.commons.CommonsMultipartResolver">

            <!-- one of the properties available; the maximum file size in bytes -->
            <property name="maxUploadSize" value="100000"/>
    </bean>

    <context:component-scan base-package="com.everbank.uldd" scoped-proxy="targetClass"/>


您可能有另一个包含服务bean的bean定义的文件-AuthenticationService等,通过web.xml文件声明:

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>service..</param-value>
</context-param>

上下文配置位置
服务
如果是这样,您还需要在测试中包含此配置


另外,对于Spring mvc测试,我强烈建议改用。

组件扫描上的CustomScopeConfigurer和作用域代理背后的原因是什么。@dardo-虽然有很多解决方案需要谷歌搜索(包括将对象重新定义为测试上下文的原型/sinlgeton,注入模拟http会话和请求),拥有一个简单的线程绑定会话作用域的最简单方法就是在测试IoC配置中声明它,如下所示。请记住,junit默认在单个线程中触发所有测试,因此状态在测试之间保持不变。请看-谢谢你的回复。到目前为止,my web.xml仅引用root-context.xml.Yes,但您可能对root-context.xml中的服务类进行了组件扫描。这就是创建AuthenticationService bean的原因,如果该bean不存在于您的上下文中,它将不会自动连接到您的控制器中。实际上,我在根上下文中没有任何组件扫描<代码>哦,好吧,我现在明白你的问题了,你在@Before方法中实例化了一个新的LoginController和一个新的AuthenticationService,对吧,这将清除你自动连接到测试中的所有内容?
<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>service..</param-value>
</context-param>