2016-09-14 11 views
7

は、私はいくつかの情報のために、残りを介して外部のサーバに依頼する必要のあるサービスを持っている:RESTテンプレート交換を模擬するにはどうすればよいですか?

public class SomeService { 

    public List<ObjectA> getListofObjectsA() { 
     List<ObjectA> objectAList = new ArrayList<ObjectA>(); 
     ParameterizedTypeReference<List<ObjectA>> typeRef = new ParameterizedTypeReference<List<ObjectA>>() {}; 
     ResponseEntity<List<ObjectA>> responseEntity = restTemplate.exchange("/objects/get-objectA", HttpMethod.POST, new HttpEntity<>(ObjectAList), typeRef); 
     return responseEntity.getBody(); 
    } 
} 

はどのようgetListofObjectsA()のためのJUnitテストを書くことができますか?上記のコードは動作しません。しかし、

@RunWith(MockitoJUnitRunner.class) 
public class SomeServiceTest { 
    private MockRestServiceServer mockServer; 

    @Mock 
    private RestTemplate restTemplate; 

    @Inject 
    private SomeService underTest; 

@Before 
public void setup() { 
    mockServer = MockRestServiceServer.createServer(restTemplate); 
    underTest = new SomeService(restTemplate); 
    mockServer.expect(requestTo("/objects/get-objectA")).andExpect(method(HttpMethod.POST)) 
      .andRespond(withSuccess("{json list response}", MediaType.APPLICATION_JSON)); 
} 

    @Test 
    public void testGetObjectAList() { 
    List<ObjectA> res = underTest.getListofObjectsA(); 
    Assert.assertEquals(myobjectA, res.get(0)); 
} 

それはresponseEntittynullであることを示しています

私は以下を試してみました。 restTemplate.exchangeを正しく模擬するためにテストを修正するにはどうすればよいですか?

+1

誰もがアイデアを持っていますか? –

答えて

5

MockRestServiceServerオブジェクトは必要ありません。注釈は@InjectMocksではなく、@Injectです。ベローは、私にとって

@RunWith(MockitoJUnitRunner.class) 
public class SomeServiceTest { 
    @Mock 
    private RestTemplate restTemplate; 

    @InjectMocks 
    private SomeService underTest; 

    @Test 
    public void testGetObjectAList() { 
     ObjectA myobjectA = new ObjectA(); 
     //define the entity you want the exchange to return 
     ResponseEntity<List<ObjectA>> myEntity = new ResponseEntity<List<ObjectA>>(HttpStatus.ACCEPTED); 
     Mockito.when(restTemplate.exchange(
      Matchers.eq("/objects/get-objectA"), 
      Matchers.eq(HttpMethod.POST), 
      Matchers.<HttpEntity<List<ObjectA>>>any(), 
      Matchers.<ParameterizedTypeReference<List<ObjectA>>>any()) 
     ).thenReturn(myEntity); 

     List<ObjectA> res = underTest.getListofObjectsA(); 
     Assert.assertEquals(myobjectA, res.get(0)); 
    } 
4
ResponseEntity<String> responseEntity = new ResponseEntity<String>("sampleBodyString", HttpStatus.ACCEPTED); 
when(restTemplate.exchange(
          Matchers.anyString(), 
          Matchers.any(HttpMethod.class), 
          Matchers.<HttpEntity<?>> any(), 
          Matchers.<Class<String>> any() 
         ) 
         ).thenReturn(responseEntity); 
1

を動作するはずのコード例で、私の代わりに、私は非常に便利であるa small libraryを実装

Mockito.when(restTemplate.exchange(Matchers.any(URI.class), Matchers.any(HttpMethod.class), Matchers.<HttpEntity<?>> any(), Matchers.<Class<Object>> any())).thenReturn(myEntity); 
0

のMatchers.any(URI.class)を使用する必要がありました。これは、いくつかのコンテキストを受け取ることができるClientHttpRequestFactoryを提供します。そうすることで、クエリパラメータが評価され、ヘッダーが設定されているかどうかのチェック、およびデシリアライゼーションがうまく機能するかどうかのチェックなど、すべてのクライアントレイヤーを調べることができます。

0

残りの呼び出しを気にせずにサービスをテストすることを意図している場合は、単体テストでアノテーションを使用しないことをお勧めします。

私の提案は、注入コンストラクタを使用してresttemplateを受け取るようにあなたのサービスをリファクタリングすることです。これによりテストが容易になります。例:

@Component 
public class RestTemplateObjects { 

    private final RestTemplate restTemplate; 

    public RestTemplateObjects() { 
     this.restTemplate = new RestTemplate(); 
     // you can add extra setup the restTemplate here, like errorHandler or converters 
    } 

    public RestTemplate getRestTemplate() { 
     return restTemplate; 
    } 
} 

とテスト:後に注入し、嘲笑する成分として

@Service 
class SomeService { 
    @AutoWired 
    SomeService(TestTemplateObjects restTemplateObjects) { 
     this.restTemplateObjects = restTemplateObjects; 
    } 
} 

RestTemplateこのように

public void test() { 

    when(mockedRestTemplateObject.get).thenReturn(mockRestTemplate); 

    //mock restTemplate.exchange 
    when(mockRestTemplate.exchange(...)).thenReturn(mockedResponseEntity); 

    SomeService someService = new SomeService(mockedRestTemplateObject); 
    someService.getListofObjectsA(); 
} 

、あなたはモックに直接アクセスすることがSomeServiceコンストラクタによってテンプレートを休止します。

関連する問題