2016-10-25 7 views
0

샘플 응용 프로그램에서 @PathVariable 주석 컨트롤러와 @WebMcvTest 결합하는 것은 여기에 있습니다 : 나는 봄 부팅 1.4.1을 사용하여 새 프로젝트를 부트 스트랩하고 https://github.com/olemerdy-fa/webmvctest는이 질문에 대한 봄 부트 1.41

. 필자는이 위대한 프레임 워크의 새로운 기능, 특히 응용 프로그램의 (아주) 단위 테스트 슬라이스에 대한 기능을 활용하려고합니다.

주석이 달린 메서드 @PathVariable을 선언 할 때 @Controller에 사용할 때 @WebMvcTest 기능으로 고민하고 있습니다.

사실, @WebMvcTest은 다른 컨트롤러를 제공하지 않고 단일 컨트롤러와 MockMvc 테스트 기능을 부트 스트랩하기로되어 있습니다. @MockBean을 사용하면,이 컨트롤러 내부에 주입하기 위해 의존성 (mocks)을 제공하는 것은 여전히 ​​쉽습니다.

그러나 스프링 데이터가 일반적으로 등록한 JPA 엔티티 유형은 @PathVariable입니다.

  • MyEntity
  • Webmvctest1Controller 경로에서 ID를 검색하는 load 방법을 가지고 있으며, 간단한 JPA 엔티티와 MyEntityRepository의 봄 데이터 관련 저장소입니다 :

    샘플 프로젝트는이 질문은 몇 가지 샘플이 포함되어 있습니다에 합류 MyEntityRepository.findOne(id) 메서드라고 부릅니다.

  • Webmvctest1ControllerUnitTestMyEntityRepository을 조롱하여이 컨트롤러를 테스트하며 모든 것이 잘 진행됩니다.
  • 나는이 같은 모의 개체를 제공하는 방법을 알고하지 않는 한, 붙어 곳
  • Webmvctest2Controllerload 봄 데이터에 의해보고 된 @PathVariable 주석 MyEntity와 방법 등록 계산기

    @RestController 
    public class Webmvctest2Controller { 
    
        @RequestMapping("load2/{id}") 
        public MyEntity load2(@PathVariable("id") MyEntity myEntity) { 
         return myEntity; 
        } 
    
    } 
    
  • Webmvctest2ControllerUnitTest이다가 파라미터 여전히 이것은 org.springframework.web.method.annotation.MethodArgumentConversionNotSupportedException 예외 실패 MockMvc

    @RunWith(SpringRunner.class) 
    @WebMvcTest(Webmvctest2Controller.class) 
    public class Webmvctest2ControllerUnitTest { 
    
        @Autowired 
        private MockMvc mvc; 
    
        @Test 
        public void load2() throws Exception { 
    
         // How do I mock converter to PathVariable here? 
    
         mvc.perform(get("/load2/123").accept(MediaType.APPLICATION_JSON)) 
           .andExpect(status().isOk()) 
           .andExpect(content().json("{id:123,name:'My Entity 123'}")); 
        } 
    
    } 
    

사용시

2016-10-25 14:27:55.699 WARN 20753 --- [   main] .w.s.m.s.DefaultHandlerExceptionResolver : Failed to convert request element: org.springframework.web.method.annotation.MethodArgumentConversionNotSupportedException: Failed to convert value of type [java.lang.String] to required type [com.stackoverflow.MyEntity]; nested exception is java.lang.IllegalStateException: Cannot convert value of type [java.lang.String] to required type [com.stackoverflow.MyEntity]: no matching editors or conversion strategy found 

    MockHttpServletRequest: 
      HTTP Method = GET 
      Request URI = /load2/123 
      Parameters = {} 
       Headers = {Accept=[application/json]} 

    Handler: 
       Type = com.stackoverflow.Webmvctest2Controller 
       Method = public com.stackoverflow.MyEntity com.stackoverflow.Webmvctest2Controller.load2(com.stackoverflow.MyEntity) 

    Async: 
     Async started = false 
     Async result = null 

    Resolved Exception: 
       Type = org.springframework.web.method.annotation.MethodArgumentConversionNotSupportedException 

    ModelAndView: 
      View name = null 
       View = null 
       Model = null 

    FlashMap: 
      Attributes = null 

    MockHttpServletResponse: 
       Status = 500 
     Error message = null 
       Headers = {} 
     Content type = null 
       Body = 
     Forwarded URL = null 
     Redirected URL = null 
       Cookies = [] 
    Tests run: 1, Failures: 1, Errors: 0, Skipped: 0, Time elapsed: 0.375 sec <<< FAILURE! - in com.stackoverflow.Webmvctest2ControllerUnitTest 
    load2(com.stackoverflow.Webmvctest2ControllerUnitTest) Time elapsed: 0.015 sec <<< FAILURE! 
    java.lang.AssertionError: Status expected:<200> but was:<500> 
      at org.springframework.test.util.AssertionErrors.fail(AssertionErrors.java:54) 
      at org.springframework.test.util.AssertionErrors.assertEquals(AssertionErrors.java:81) 
      at org.springframework.test.web.servlet.result.StatusResultMatchers$10.match(StatusResultMatchers.java:664) 
      at org.springframework.test.web.servlet.MockMvc$1.andExpect(MockMvc.java:171) 
      at com.stackoverflow.Webmvctest2ControllerUnitTest.load2(Webmvctest2ControllerUnitTest.java:28) 
  • WebmvctestApplicationTests

    응용 프로그램이 완전히

여전히 @WebMvcTest 내 웹 슬라이스를 테스트하는 동안 내 @PathVariable 개체 매개 변수를 유지할 수있는 방법의 어떤 생각 부트 스트랩 때 모든 것이 두 경우 모두에서 좋은 것을 보여준다 ? 감사합니다 :)

+0

_ "@WebMvcTest는 다른 컨트롤러를 제공하지 않고 단일 컨트롤러와 MockMvc 테스트 기능을 부트 스트랩하기로되어 있습니다."_ 기본적으로 자신의 질문에 답변 했으므로 어떤 대답을 기대하는지 확신 할 수 없습니다. 'MockMvc'를 사용하기 위해'@WebMvcTest'가 필요 없습니다. 더 중요한 것은 요청에 시체가 없기 때문에 메서드가 매개 변수로 엔티티를 기대해야하는 이유는 무엇입니까? – zeroflagL

+0

여기에 제공된 샘플은 무슨 일이 일어나고 있는지 간단하게 보여줍니다. 실제 코드에서이 메소드는 단순히 엔티티를 전달하는 것이 아니라이를 수정할 수 있고 하위 속성을 요청하고 여러 개의 변환 메소드를 사용할 수 있습니다. 실제로 요청 서명에있는 엔티티를 로딩하는 것이 문제라면, 스프링에 의해 네이티브로 등록되지 않은 변환기 (Joda Money)에 대해서는 질문이 유효합니다. –

+0

여기서 모든 것을로드 할 때만 컨트롤러를 테스트 할 수 있습니다. 나는 (http://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-testing.html) 몇 가지 서비스만을로드하는 조각의 정신을 유지하는 해결책을 찾고있다. 테스트 할 레이어 (여기서 웹 파트 만, 데이터 또는 서비스 레이어는 제외)입니다. 원래 컨트롤러 코드를 수정하지 않고 웹 컨트롤러를로드하고 모든 종속성을 모방하기 위해 할 수있는 작업은 무엇입니까? (@PathVariable 풍부한 유형을 유지하고 Spring에서 변환을 처리하도록할까요?) –

답변

1

HandlerMethodArgumentResolver에 가능한 공헌에 대해 @zeroflagL 힌트를 주심에 감사 드리며, 필자의 요구에 맞는 해결책을 찾았습니다.컨트롤러에서 모의 ​​개체 주입을 처리하는 사용자 정의 변환기 기여하는 작업 모의 법인이 시험 방법 자체에서 제공하지만 여전히 할 수 없기 때문에 그것은, 완벽하지

@RunWith(SpringRunner.class) 
    @WebMvcTest(Webmvctest2Controller.class) 
    public class Webmvctest2ControllerUnitTest { 

     @Autowired 
     private MockMvc mvc; 

     @Test 
     public void load2() throws Exception { 
      mvc.perform(get("/load2/123").accept(MediaType.APPLICATION_JSON)) 
        .andExpect(status().isOk()) 
        .andExpect(content().json("{id:123,name:'My Entity'}")); 
     } 

     @TestConfiguration 
     static class InternalConfig { 

      @Bean 
      WebMvcConfigurer configurer() { 
       return new WebMvcConfigurerAdapter() { 
        @Override 
        public void addFormatters(FormatterRegistry registry) { 
         registry.addConverter(String.class, MyEntity.class, id -> { 
          if (id.equals("123")) { 
           MyEntity myEntity = new MyEntity(123); 
           myEntity.setName("My Entity"); 
           return myEntity; 
          } 
          throw new IllegalArgumentException(); 
         }); 
        } 
       }; 
      } 
     } 
    } 

을 할 것으로 보인다 웹 장치를 할 수 있습니다 테스트 용 부트 스트랩과 실행을 유지하고 싶었습니다.