【问题标题】:Spring Boot: How to inject server.contextPath from application.properties into MockServletContextSpring Boot:如何将 application.properties 中的 server.contextPath 注入 MockServletContext
【发布时间】:2018-09-07 05:53:14
【问题描述】:

在 application.properties 我配置了server.contextPath=/app-service

很遗憾,测试上下文中不存在此值:

@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = { Application.class, SwaggerConfig.class })
@WebAppConfiguration
public class Swagger2MarkupTest {

    @Autowired
    private WebApplicationContext context;

    private MockMvc mockMvc;

    @Before
    public void setUp() {
        this.context.getServletContext().getContextPath(); // null
        this.mockMvc = MockMvcBuilders.webAppContextSetup(this.context).build();
    }
}

我需要默认使用的 Swagger Docket 的 contextPath springfox.documentation.spring.web.paths.RelativePathProvider 通过

确定 contextPath
  @Override
  protected String applicationPath() {
    return isNullOrEmpty(servletContext.getContextPath()) ? ROOT : servletContext.getContextPath();
  }

这都是关于在单元测试之前被调用的 RelativePathProvider。这与将 contextPath 注入到单元测试本身无关,因为相对路径提供者已经为 SwaggerConfiguration 调用了servletContext.getContextPath(),所以它已经很晚了。

【问题讨论】:

    标签: spring-boot swagger springfox contextpath


    【解决方案1】:

    您可以通过多种方式实现这一目标,以下是其中两种:

    1. 注入springEnvironment并获取属性值:

      @RunWith(SpringJUnit4ClassRunner.class)
      @SpringBootTest(classes = { Application.class, SwaggerConfig.class })
      @WebAppConfiguration
      public class Swagger2MarkupTest {
      
          @Autowired
          private WebApplicationContext context;
      
          @Autowired
          private Environment environment;
      
          private MockMvc mockMvc;
      
          @Before
          public void setUp() {
              environment.getProperty("server.contextPath"); // should return /app-service
              this.mockMvc = MockMvcBuilders.webAppContextSetup(this.context).build();
          }
      }
      
    2. 使用@Value注入它:

      @RunWith(SpringJUnit4ClassRunner.class)
      @SpringBootTest(classes = { Application.class, SwaggerConfig.class })
      @WebAppConfiguration
      public class Swagger2MarkupTest {
      
          @Autowired
          private WebApplicationContext context;
      
          @Value("server.contextPath")
          private String contextPath; // should populate with /app-service
      
          private MockMvc mockMvc;
      
          @Before
          public void setUp() {
              this.mockMvc = MockMvcBuilders.webAppContextSetup(this.context).build();
          }
      }
      

    【讨论】:

    • 我知道,但这不是我想要的。我不想在 UnitTest 中获取 contextPath,我希望它在 ServletContext 中(在单元测试开始之前),以便 RelativePathProvider 通过 servletContext.getContextPath() 获取它
    • 您可以尝试使用WebEnvironment.RANDOM_PORT:@SpringBootTest(classes = { Application.class, SwaggerConfig.class }, webEnvironment = WebEnvironment.RANDOM_PORT) 看看更改为EmbeddedWebApplicationContext 是否也会更改为您期望的行为?一般来说,springfox 应该与您使用的配置和属性保持一致,因为它是基于 spring 的模块。
    • UnitTest 根本没有启动:org.springframework.test.context.support.AbstractContextLoader - 无法检测到测试类的默认资源位置 [....Swagger2MarkupTest]:找不到后缀的资源 { -context.xml, Context.groovy}.
    猜你喜欢
    • 2019-03-18
    • 2021-11-24
    • 2017-07-12
    • 2021-02-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-17
    • 2017-08-07
    相关资源
    最近更新 更多