2016-06-24 2 views
0

У меня есть простой контроллер Spring MVC, чья RequestMapping является свойством. Это банку с контроллером. Downstream-приложения будут использовать эту банку и использовать общую конечную точку, только точный URL-адрес может варьироваться в зависимости от приложения)RequestMapping placeholders не работают в тестах JUnit

Все работает нормально, когда я включаю свою банку в другое приложение. Приложение имеет свойство или файл yaml, и свойство установлено. Я проверил, что конечная точка работает нормально.

Однако, будучи хорошим разработчиком, которым я являюсь, я хочу сделать интеграционный тест, который проверяет, что URL-адрес, определенный свойством, отображается правильно. Я могу получить значение @Value в контроллере правильно, но выражение $ {} в @RequestMapping не будет заменено из файла свойств. Я нашел пару потоков (Spring Boot REST Controller Test with RequestMapping of Properties Value и @RequestMapping with placeholder not working) Но либо они не применяются, либо я попробовал, что они сказали, и я не мог заставить его работать.

Тестирование, которое попадает в статическую (iWork) конечную точку, работает, но тот, который вытащил из свойства (iDontWork), не работает.

(Это весна 4.2.6)

Контроллер

@RestController 
@RequestMapping(value = {"/${appName}", "/iWork"}) 
public class Controller { 

    @Value("${appName}") 
    private String appName; 

    @RequestMapping(method= RequestMethod.GET) 
    public String handlerMethod (HttpServletRequest request) throws Exception { 
     // Proves the placeholder is injected in the class, but 
     // Not in the RequestMapping 
     assert appName != null; 
     assert !appName.equals("${appName}"); 
     return ""; 
    } 
} 

ControllerTest

@WebAppConfiguration 
@RunWith(SpringJUnit4ClassRunner.class) 
@ContextConfiguration(loader = AnnotationConfigWebContextLoader.class, 
    classes = { ControllerTest.Config.class }) 
public class ControllerTest { 

    @Autowired 
    private WebApplicationContext context; 

    private MockMvc mvc; 

    @Before 
    public void setup() { 
     mvc = MockMvcBuilders 
      .webAppContextSetup(context) 
      .build(); 
    } 

    @Configuration 
    @ComponentScan(basePackages = {"test"}) 
    static class Config { 
     // because @PropertySource doesnt work in annotation only land 
     @Bean 
     PropertyPlaceholderConfigurer propConfig() { 
      PropertyPlaceholderConfigurer ppc = new PropertyPlaceholderConfigurer(); 
      ppc.setLocation(new ClassPathResource("test.properties")); 
      return ppc; 
     } 
    } 

    @Test 
    public void testStaticEndpoint() throws Exception { 
     mvc.perform(get("/iWork")).andExpect(status().isOk()); 
    } 

    @Test 
    public void testDynamicEndpoint() throws Exception { 
     mvc.perform(get("/iDontWork")).andExpect(status().isOk()); 
    } 
} 

test.properties

appName = iDontWork 

ответ

1

Вы "просто" не хватает

@EnableWebMvc 

на вашем @Configuration классе. Без него Spring Mock MVC stack зарегистрирует методы обработчика контроллера с помощью DefaultAnnotationHandlerMapping, который недостаточно умен, чтобы разрешить заполнители в @RequestMapping.

Если у вас есть do, то Mock MVC вместо этого использует RequestMappingHandlerMapping.

0

При создании mockMvc вам необходимо добавить значение placeholder, как показано ниже.

@Before 
public void setup() { 
    MockitoAnnotations.initMocks(this); 
    mockMvc = MockMvcBuilders.standaloneSetup(accountController) 
       .addPlaceholderValue("propertyName", "propertyValue") 
       .build(); 
} 
Смежные вопросы