2016-09-14 10 views
7

Tôi có một dịch vụ mà tôi cần phải hỏi một máy chủ bên ngoài thông qua phần còn lại cho một số thông tin:Làm cách nào để giả lập một trao đổi mẫu 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(); 
    } 
} 

Làm thế nào tôi có thể viết một bài kiểm tra JUnit cho getListofObjectsA()?

Tôi đã thử với dưới đây:

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

Tuy nhiên các mã trên không hoạt động, nó cho thấy rằng responseEntittynull. Làm thế nào tôi có thể sửa thử nghiệm của tôi để thử nghiệm đúng cách restTemplate.exchange?

+1

có ai có ý tưởng không? –

Trả lời

5

Bạn không cần đối tượng MockRestServiceServer. Chú thích là @InjectMocks không phải là @Inject. Bellow là một mã số ví dụ mà nên làm việc

@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

Đối với tôi, tôi đã phải sử dụng Matchers.any (URI.class) thay vì

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

tôi thực hiện a small library đó là khá hữu ích. Nó cung cấp một ClientHttpRequestFactory có thể nhận được một số ngữ cảnh. Bằng cách làm như vậy, nó cho phép đi qua tất cả các lớp của khách hàng như kiểm tra các tham số truy vấn có giá trị, các tiêu đề được đặt và kiểm tra xem quá trình deserialization có hoạt động tốt hay không.

0

Nếu ý định của bạn là kiểm tra dịch vụ mà không cần quan tâm đến cuộc gọi còn lại, tôi sẽ đề nghị không sử dụng bất kỳ chú thích nào trong bài kiểm tra đơn vị của bạn để đơn giản hóa bài kiểm tra.

Vì vậy, đề xuất của tôi là cấu trúc lại dịch vụ của bạn để nhận phần còn lại bằng cách sử dụng hàm tạo phun. Điều này sẽ tạo thuận lợi cho thử nghiệm. Ví dụ:

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

Các RestTemplate như thành phần, được tiêm và chế giễu sau:

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

Và kiểm tra:

public void test() { 

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

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

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

Bằng cách này, bạn có thể truy cập trực tiếp để chế nhạo các phần còn lại của trình xây dựng SomeService.

Các vấn đề liên quan