带有属性值的 RequestMapping 的 Spring Boot REST 控制器测试

Posted

技术标签:

【中文标题】带有属性值的 RequestMapping 的 Spring Boot REST 控制器测试【英文标题】:Spring Boot REST Controller Test with RequestMapping of Properties Value 【发布时间】:2016-01-29 09:38:34 【问题描述】:

关于 Spring Boot REST 控制器的单元测试,我遇到了 @RequestMapping 和应用程序属性的问题。

@RestController
@RequestMapping( "$base.url" )
public class RESTController 
    @RequestMapping( value = "/path/to/param", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE )
    public String getStuff( @PathVariable String param ) 
        // implementation of stuff
    

我正在处理应用程序的多个配置文件,因此我有多个 application-profile.properties 文件。在每个文件中,base.url 属性值已设置并存在。我还有一个不同的 Spring Context Configuration 用于测试,它与生产版本只有一个 Bean 不同。

使用 JUNit 和 Mockito / RestAssured,我的单元测试如下所示:

@ActiveProfiles( "dev" )
@RunWith( SpringJUnit4ClassRunner.class )
@SpringApplicationConfiguration( classes = SpringContextConfigTest.class )
public class RESTControllerTest 

private static final String SINGLE_INDIVIDUAL_URL = "/query/api/1/individuals/";

@InjectMocks
private RESTController restController;

@Mock  
private Server mockedServer; // needed for the REST Controller to forward

@Before
public void setup() 
  RestAssuredMockMvc.mockMvc( MockMvcBuilders.standaloneSetup(restController).build() );
 MockitoAnnotations.initMocks( this );


@Test
public void testGetStuff() throws Exception 
  // test the REST Method "getStuff()"

问题是,REST 控制器在生产模式下启动时正在工作。在单元测试模式下,构建mockMvc对象时,$base.url的值没有设置并抛出异常:

java.lang.IllegalArgumentException: Could not resolve placeholder 'base.url' in string value "$base.url"

我也尝试了以下方法,但有不同的例外:

@IntegrationTest 在测试中, @WebAppConfiguration, 使用webApplicationContext 构建MockMVC 在测试中自动装配 RESTController 在 SpringContextConfigTest 类中手动定义 REST 控制器 Bean

和其他各种组合,但似乎没有任何效果。 那么我必须如何继续,才能让它发挥作用呢? 我认为这是两个不同配置类的上下文配置问题,但我不知道如何解决或如何“正确”地做到这一点。

【问题讨论】:

您能否提供一个最小但完整的独立项目来说明问题? 【参考方案1】:

您需要在独立设置中添加占位符值 -

mockMvc=MockMvcBuilders.standaloneSetup(youController).addPlaceholderValue(name, value);

【讨论】:

如果 @ActiveProfiles("dev") 的唯一目的是导入占位符,则可以通过此修复删除该注释。【参考方案2】:

我通过使用一个application.yml 文件而不是配置文件属性解决了这个问题。 yml 文件使用default 配置文件的标准定义,该配置文件定义在文件顶部。

#default settings. these can be overriden for each profile.
#all these settings are overriden by env vars by spring priority
rest:
  api:
    version: 1
base:
   url: /query/api/$rest.api.version
---
spring:
   profiles: dev
---
spring:
   profiles: production
main:
  show_banner: true
---
spring:
   profiles: test
base:
   url: /query/override/default/value

【讨论】:

【参考方案3】:

似乎在非生产模式下无法解析属性占位符。您肯定想查看PropertyPlaceholderConfigurer 文档页面。

这个answer 也可以提供一些实施帮助。

【讨论】:

以上是关于带有属性值的 RequestMapping 的 Spring Boot REST 控制器测试的主要内容,如果未能解决你的问题,请参考以下文章

@RequestMapping注解的6+2个属性---6.11

带有斜线和点的 RequestMapping

Java 之 Properties 集合

带有可选参数的 Spring @RequestMapping

SpringMVC— “@RequestMapping注解及其属性”

SpringMVC— “@RequestMapping注解及其属性”