Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring MVC Integration test - how look up request Mapping path?

We have some controller, say something like this:

@Controller
@RequestMapping("/api")
public Controller UserController {

    @RequestMapping("/users/{userId}")
    public User getUser(@PathVariable String userId){
        //bla
    }
}

We have an Integration test for this, say:

@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
@SpringApplicationConfiguration(classes= MyApp.class)
@IntegrationTest("server:port:0")
public class UserControllerIT {

    @Autowired
    private WebApplicationContext context;

    @Test
    public void getUser(){
        test().when()
                .get("/api/users/{userId}", "123")
                .then()
                .statusCode(200);
    }
}

How can we avoid hard coding the "/api/users/{userId}" in the test? How can we look up the requestmapping by name. The above request mapping should have a default name of UC#getUser

The only thing I've seen is something like MvcUriComponentsBuilder, which appears to require that it be used within the context of a request (so it would be used in .jsps to generate URLs to controllers).

What is the best way to handle this? Do I have to expose the mappings as static strings on the controllers? I'd prefer to at least avoid that.

like image 694
Dan Avatar asked Feb 10 '16 17:02

Dan


2 Answers

Something like:

URI location = MvcUriComponentsBuilder.fromMethodCall(on(UserController.class).getUser("someUserId").build().toUri();
like image 99
wwadge Avatar answered Sep 22 '22 07:09

wwadge


I ended up doing as @DavidA suggested and just using reflection:

protected String mapping(Class controller, String name) {
    String path = "";
    RequestMapping classLevel = (RequestMapping) controller.getDeclaredAnnotation(RequestMapping.class);
    if (classLevel != null && classLevel.value().length > 0) {
        path += classLevel.value()[0];
    }
    for (Method method : controller.getMethods()) {
        if (method.getName().equals(name)) {
            RequestMapping methodLevel = method.getDeclaredAnnotation(RequestMapping.class);
            if (methodLevel != null) {
                path += methodLevel.value()[0];
                return url(path);
            }
        }
    }
    return "";
}

I don't know how often we'll use it but this is the best I could find.

Usage in a test class:

when().get(mapping(UserAccessController.class, "getProjectProfiles"), projectId)
            .then().assertThat().body(....);
like image 30
Dan Avatar answered Sep 22 '22 07:09

Dan