2016-10-25 8 views
0

サンプル・アプリケーションはここにある:https://github.com/olemerdy-fa/webmvctestは春ブーツで@PathVariable注釈付きのコントローラと組み合わせる@WebMcvTestこの質問に対して1.41

私は春のブート1.4.1を使用して新しいプロジェクトをブートストラップしています。私は、この偉大なフレームワークの新機能、特に私のアプリケーションの(かなり)ユニットテストのスライスを活用することを試みています。

注釈付きメソッドを宣言するには@Controllerで使用すると、今は@WebMvcTest機能で苦労しています。

実際、@WebMvcTestは、何も提供せずに、単一のコントローラとMockMvcテスト機能をブートストラップすることになっています。 @MockBeanを使用すると、このコントローラの内部に注入するためのモックを依存関係として提供するのはまだ簡単です。

しかし、そのタイプは、通常、Springデータによってコンバーターが登録されているJPAエンティティのタイプのアノテーション付きパラメータはどうでしょうか?

サンプルプロジェクトは、この質問に接合は、いくつかのサンプルを含む:

  • MyEntityは、単純なJPAエンティティであるとMyEntityRepositoryそのスプリングデータ関連リポジトリ
  • Webmvctest1ControllerパスからIDを取得load方法を有しており、 MyEntityRepository.findOne(id)メソッド
  • Webmvctest1ControllerUnitTestMyEntityRepositoryをモックしてこのコントローラをテストし、すべてがうまくいくといいます。
  • 私は私のようにモックエンティティを提供する方法がわからないよう、こだわっているところ
  • Webmvctest2Controllerload春データによって検索され@PathVariable注釈付きMyEntityと方法登録コンバータ

    @RestController 
    public class Webmvctest2Controller { 
    
        @RequestMapping("load2/{id}") 
        public MyEntity load2(@PathVariable("id") MyEntity myEntity) { 
         return myEntity; 
        } 
    
    } 
    
  • Webmvctest2ControllerUnitTestをされていますパラメータまだ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'}")); 
        } 
    
    } 
    

を使用しながら、これはorg.springframework.web.method.annotation.MethodArgumentConversionNotSupportedException例外で失敗

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で私のWebスライスをテストしながら、私は私の@PathVariableエンティティパラメータを保つことができる方法の任意のアイデアブートストラップされたときにすべてが両方のケースで罰金であることを示しています? ありがとう:)

+0

_ "@WebMvcTestは、単一のコントローラとMockMvcテスト機能を他のものを用意することなくブートストラップすることになっています。" _基本的にあなた自身の質問に答えています。 'MockMvc'を使うのに' @ WebMvcTest'は必要ありません。さらに重要なことは:リクエストにはボディがないため、メソッドがエンティティをパラメータとして期待するのはなぜですか? – zeroflagL

+0

ここに示したサンプルは、何が起こっているかを簡単に示しています。実世界のコードでは、このメソッドは単純にエンティティを転送するのではなく、それを変更したり、サブプロパティを要求したり、複数のコンバチブルメソッドを使用したりすることができます。実際には、リクエストシグネチャのエンティティを読み込むことが問題である場合、Springのネイティブ登録されていないコンバーター(Joda Moneyなど)でも問題は有効です。 –

+0

ここでは、すべてをロードするときだけコントローラをテストできます。私は、いくつかのサービスをロードするだけのスライス(http://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-testing.html)の精神を保つソリューションを探しています。レイヤー(ここでは、データまたはサービスレイヤーではなくWebパーツのみ)をテストしています。元のコントローラコードを変更せずに、Webコントローラをロードしてすべての依存関係をモックするだけで何ができますか(@PathVariableの豊富な型を保持し、Springがコンバージョンを処理するようにします) –

答えて

1

@zeroflagLのおかげで、HandlerMethodArgumentResolverへの貢献が示唆されたので、私は自分の必要性に合った解決策を思いつきました。コントローラにモックエンティティ注入を取り扱うカスタムコンバータを貢献する

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

仕事をしているようだ模擬エンティティは、試験法自体では提供できないように、それは、完璧ではないですが、それはまだウェブ・ユニットを可能ですテストのブートストラップと実行私は維持したかった。

関連する問題