2016-03-21 19 views
2

私は、Spring-Jerseyの注釈付きアプリケーションがあります。 JerseyTestを使用してコントローラのユニットテストを設定しようとしています。私が理解できないテストを実行する際に、次のエラーが発生しています。私は何を逃したのですか?次のようにSpring-Jerseyアプリケーション用のJerseyTestでのリソース・モデルの検証に失敗しました

SEVERE: Following issues have been detected: 
WARNING: No injection source found for a parameter of type public com.example.services.dto.UnitDto com.example.apis.UnitResource.getUnits(com.example.services.dto.PointDto) throws com.example.exceptions.PointOutsideBounds at index 2. 

Validation of the application resource model has failed during application initialization. 
[[FATAL] No injection source found for a parameter of type public com.example.services.dto.UnitDto com.example.apis.UnitResource.getUnits(com.example.services.dto.PointDto) throws com.example.exceptions.PointOutsideBounds at index 2.; source='ResourceMethod{httpMethod=GET, consumedTypes=[], producedTypes=[application/json], suspended=false, suspendTimeout=0, suspendTimeoutUnit=MILLISECONDS, invocable=Invocable{handler=ClassBasedMethodHandler{handlerClass=class com.example.apis.UnitResource, handlerConstructors=[[email protected]]}, definitionMethod=public com.example.services.dto.UnitDto com.example.apis.UnitResource.getUnits(com.example.services.dto.PointDto) throws com.example.exceptions.PointOutsideBounds, parameters=[Parameter [type=class com.example.services.dto.PointDto, source=contains, defaultValue=null]], responseType=class com.example.services.dto.UnitDto}, nameBindings=[]}'] 
    at org.glassfish.jersey.server.ApplicationHandler.initialize(ApplicationHandler.java:555) 

コントローラクラスがある:

@Component 
@Path("/app/units") 
public class UnitResource { 
    @Context 
    private UriInfo uriInfo; 
    @Context 
    private Request request; 

    @Inject 
    private UnitService unitService; 

    @Inject 
    public UnitResource(@Named("UnitService") UnitService unitService) { 
     this.unitService = unitService; 
    } 

    @GET 
    @Produces(MediaType.APPLICATION_JSON) 
    @Timed(absolute = true, name = "getUnitForPoint") 
    public UnitDto getUnits(@QueryParam("contains") @NotNull PointDto point) throws PointOutsideBounds { 
     return unitService.getUnitForPoint(point); 
    } 
} 

次のようにテスト・クラスがある:

public class UnitResourceTest extends JerseyTest { 

    @Mock 
    private UnitService unitService; 

    @Override 
    protected ResourceConfig configure() { 
     ResourceConfig rc = new ResourceConfig() 
     //  .register(new UnitResource(Mockito.mock(UnitService.class))) -- has the same effect 
       .register(UnitResource.class) 
       .property("contextConfig", new AnnotationConfigApplicationContext(ApplicationConfiguration.class)); 

     enable(TestProperties.LOG_TRAFFIC); 
     enable(TestProperties.DUMP_ENTITY); 
     forceSet(TestProperties.CONTAINER_PORT, "0"); 

     return rc; 
    } 

    @Before 
    public void setUp() throws Exception { 
     super.setUp(); 
     initMocks(this); 
    } 

    @Override 
    protected TestContainerFactory getTestContainerFactory() { 
     return new InMemoryTestContainerFactory(); 
    } 

    @Test 
    public void testGetUnit() throws PointOutsideBounds { 

     Response response = target() 
       .path("/app/units") 
       .queryParam("contains", new Point(0.0,0.0).toJson()) 
       .request(MediaType.APPLICATION_JSON_TYPE) 
       .get(); 

     assertThat(response.getStatus(), is(Response.Status.OK)); 
    } 
} 

アプリケーション・コンフィギュレーション・クラスがある:

@Configuration 
@ComponentScan("com.example") 
public class ApplicationConfiguration { 
    @Bean(name="UnitService") 
    public UnitService unitService() { 
     return new UnitService(); 
    } 
} 

マイのGradleテスト構成の依存関係は次のとおりです。

​​

私はthisthisを見つけましたが、どちらも私の問題を解決しました。

答えて

0

注:ほとんどの場合、この回答はすべての@XxxParam注釈付きパラメータに適用されます。

PointDtoパラメータは

public UnitDto getUnits(@QueryParam("contains") @NotNull PointDto point) 

クエリパラメータは文字列です問題のようです。 Jerseyは、そのStringをint,booleanDateなどのような基本的な型に変換する機能を持っていますが、そのStringからPointDtoを作成する方法はわかりません。つまり、カスタムタイプを使用できないというわけではありません。

  1. Stringを受け入れるコンストラクタを用意してください。それから、そのStringからオブジェクトを構築する必要があります。たとえば、

    public PointDto(String param) { 
        Map<String, Object> map = parseJson(param); 
        this.field1 = map.get("field1"); 
        this.field2 = map.get("field2"); 
    } 
    

    これはちょっとした作業です。

  2. もう一つの選択肢は、スタティックfromString(String)またはスタティックvalueOf(String)をクラスに含めることです。 Jerseyはこのメソッドを呼び出してオブジェクトを構築します。例えばあなたがPointDtoクラス

    public static PointDto fromString(String param) { 
        PointDto dto = parseJson(param); 
        return dto; 
    } 
    
  3. に持つことができますので、ParamConverterProviderを持つことができます。私は例を挙げませんが、実装方法についてはthis good articleで詳しく読むことができます。あなたはまた、this post

ノートを見ることができ、この答えに提示された情報は、@QueryParamのjavadocです。

+0

ありがとうございました。完全にそれを逃した。私は、JSONをクエリパラメータとして渡すことを再考しています。 'x、y、z'のようなコンマ区切りの文字列を送り、コントローラーの中で' PointDto'を初期化します。 – 341008

+1

さて、私はあなたがテストデープから春を除外していることに気付きました。 Spring XMLコンテクストファイルを探すときにJerseyからfilenotfoundexceptionを取得しているからです。注釈設定の使い方については、[this post](http://stackoverflow.com/a/34990765/2587435)の設定をご覧ください。そうすれば、すべてのテストでMockを使う必要がなく、テストにさまざまなSpringプロファイルを使用できます。ちょうど私がそれを持ち出すと思った。 –

+0

ありがとう、それは非常に有用です。私は単体テストを書いているので、すべてを模倣する必要があります。しかし、私は統合テストを開発するときにこれを使用します。 – 341008

関連する問題