【问题标题】:Testing Spring controller service without ApplicationContext file在没有 ApplicationContext 文件的情况下测试 Spring 控制器服务
【发布时间】:2020-04-21 23:40:02
【问题描述】:

我继承了一个不包含 ApplicationContext xml 文件并且似乎没有在应用程序中使用 ApplicationContext 的旧版应用程序。当我尝试测试时抛出以下异常:

java.lang.IllegalStateException: Failed to load ApplicationContext
    at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:124) ~[spring-test-4.3.18.RELEASE.jar:4.3.18.RELEASE]
    at 

该应用程序是一个 Spring 应用程序并且确实包含一个控制器:

@Controller
public class DataController {

但我不确定如何在没有 applicationContext 文件的情况下测试控制器服务。

这是我的测试类,它抛出java.lang.IllegalStateException

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.context.ApplicationContext;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.web.ModelAndViewAssert;
import org.springframework.web.servlet.HandlerAdapter;
import org.springframework.web.servlet.ModelAndView;

import javax.inject.Inject;

//@ContextConfiguration({/* include live config here
//    e.g. "file:web/WEB-INF/application-context.xml",
//    "file:web/WEB-INF/dispatcher-servlet.xml" */})
@RunWith(SpringJUnit4ClassRunner.class)
public class CustomTest {

        @Inject
        private ApplicationContext applicationContext;

        private MockHttpServletRequest request;
        private MockHttpServletResponse response;
        private HandlerAdapter handlerAdapter;
        private ReviewController controller;

        @Before
        public void setUp() {
            request = new MockHttpServletRequest();
            response = new MockHttpServletResponse();
            handlerAdapter = applicationContext.getBean(HandlerAdapter.class);
            // I could get the controller from the context here
            controller = new DataController();
        }

        @Test
        public void testFoo() throws Exception {
            request.setRequestURI("/data/get");
            final ModelAndView mav = handlerAdapter.handle(request, response,
                    controller);
        }
    }

如何使用签名测试DataController.getData 方法:

  @RequestMapping(value = "/data/get", method=RequestMethod.GET)
  public void getData(HttpServletResponse response, @PathVariable("dataId") long id) {

?

【问题讨论】:

    标签: java spring servlets mocking


    【解决方案1】:

    删除这个@RunWith(SpringJUnit4ClassRunner.class)

    并在 DataController.java 中使用 Mockito 进行依赖
    模拟依赖项并使用 setter 填充。

    【讨论】:

      【解决方案2】:

      做集成测试是spring 取决于项目的版本和你使用的spring boot 版本。有一篇很好的文章解释了这里(有点旧):

      https://spring.io/blog/2016/04/15/testing-improvements-in-spring-boot-1-4

      这应该为您指明正确的方向。

      根据我在较新应用程序中的经验,spring 上下文是从应用程序的 main 方法中的 Java 代码加载的。这看起来可能是其中之一。在这种情况下,您必须具备一些条件才能使集成测试发挥作用:

      1. 测试资源中的application.properties 文件,用于设置测试配置
      2. @SpringBootTest 注释的测试类
      3. 一个用@LocalServerPort注解的int属性

        @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
        public YourTestClass {
        
            @LocalServerPort
            private int port
        
            //your tests here
        
        }
        

      然后您可以设置测试并使用您想要的任何 http 客户端(RestTemplate、HttpClient 等)在本地服务器端口上调用测试应用程序。不过,这似乎有点超出了解释的范围,所以我将把它留在这里。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-05-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-03-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多