Spring Boot REST Controller Test with RequestMappi

2019-05-07 15:25发布

Regarding Unit Testing of Spring Boot REST Controller, I got a problem with @RequestMapping and application properties.

@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
    }
}

I am working with several profiles for the application and therefore I have several application-{profile}.properties files. In each file the base.url property value is set and present. I also have a different Spring Context Configuration for testing, which only differs in just one Bean from the productive version.

My Unit Test looks like the following, with using JUNit and 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()"
}

Problem is, that the REST Controller is working when started in the production mode. In the unit test mode, the ${base.url} value is not set and an exception is thrown, when building the mockMvc object:

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

I also tried it with the following approaches, but with different exceptions:

  • @IntegrationTest on Test,
  • @WebAppConfiguration,
  • using the webApplicationContext to build the MockMVC
  • autowiring the RESTController in the Test
  • defining the REST Controller Bean in the SpringContextConfigTest Class manually

and various other combinations, but nothing seems to work. So how do I have to go on, in order to make it work? I think it's a Context configuration issue with the two different config classes, but I don't know how to solve it or how to do it "right".

3条回答
Juvenile、少年°
2楼-- · 2019-05-07 15:36

It seems that in non-production mode property placeholders can't be resolved. You definitely want to look into PropertyPlaceholderConfigurer documentation page.

This answer could also provide some help with implementation.

查看更多
Emotional °昔
3楼-- · 2019-05-07 15:39

I solved the issue with using one application.yml file instead of profile-properties. The yml file is using a standard definition for the default profile, which is defined at the top of the file.

#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
查看更多
Viruses.
4楼-- · 2019-05-07 15:50

You will be required to add placeholder value to teh stand alone setup -

mockMvc=MockMvcBuilders.standaloneSetup(youController).addPlaceholderValue(name, value);
查看更多
登录 后发表回答