2016-02-10 15 views
5

Mamy jakiś kontroler, powiedzieć coś takiego:Wiosenny test integracji MVC - sposób wyszukiwania Zapytanie Ścieżka odwzorowania?

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

    @RequestMapping("https://stackoverflow.com/users/{userId}") 
    public User getUser(@PathVariable String userId){ 
     //bla 
    } 
} 

Mamy test integracyjny dla tego powiedzieć:

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

Jak możemy uniknąć twarde kodowania „/ api/Users/{ userId} "w teście? Jak możemy wyszukać żądanie mapowania według nazwy. Powyższe mapowanie żądań powinno mieć domyślną nazwę UC# getUser

Jedyne, co widziałem, to coś takiego jak MvcUriComponentsBuilder, które wydaje się wymagać użycia w kontekście żądania (aby mogło być używane w .jsps do generowania adresów URL do kontrolerów).

Jaki jest najlepszy sposób na radzenie sobie z tym? Czy muszę ujawniać mapowania jako ciągi statyczne na kontrolerach? Wolałbym przynajmniej tego uniknąć.

+0

Jeśli nie chcesz korzystać z mapowania, można użyć klasę i nazwę metody i refleksji, aby zbadać adnotacji i wyodrębnić mapowanie. – DavidA

Odpowiedz

1

skończyło się robi jak sugeruje @DavidA i tylko przy użyciu odbicia:

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 ""; 
} 

Nie wiem, jak często będziemy go używać, ale jest to najlepsze, jakie mogłem znaleźć.

Wykorzystanie w klasie testu:

when().get(mapping(UserAccessController.class, "getProjectProfiles"), projectId) 
      .then().assertThat().body(....); 
3

Coś jak:

URI location = MvcUriComponentsBuilder.fromMethodCall(on(UserController.class).getUser("someUserId").build().toUri(); 
+0

Dzięki. Zwykle unikałem tego ze względu na konieczność dostarczania argumentów metodycznych (nawet jeśli nie muszą one być ważne). Teraz już się zastanawiam ... – Dan

Powiązane problemy