2016-09-14 15 views
7

Mam usługę, w której muszę zadać serwera zewnętrznego przez resztę do niektórych informacji:W jaki sposób mogę kpić z wymiany szablonów 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(); 
    } 
} 

Jak mogę napisać test JUnit dla getListofObjectsA()?

Próbowałem z poniżej:

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

Jednakże powyższy kod nie zadziała, to pokazuje, że responseEntitty jest null. W jaki sposób mogę poprawić mój test, aby prawidłowo kpić z wersji restTemplate.exchange?

+1

ktoś ma pomysł? –

Odpowiedz

5

Nie potrzebujesz obiektu MockRestServiceServer. Adnotacja jest @InjectMocks, a nie @Inject. Poniżej znajduje się przykład kodu, który powinien działać

@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

Dla mnie, musiałem użyć Matchers.any (URI.class) zamiast

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

I wdrożone a small library że jest bardzo przydatne. Zapewnia on ClientHttpRequestFactory, który może otrzymać pewien kontekst. W ten sposób pozwala przejść przez wszystkie warstwy klienta, takie jak sprawdzanie wartości parametrów zapytania, ustawianie nagłówków i sprawdzanie, czy deserializacja działa dobrze.

0

Jeśli twoim zamiarem jest przetestowanie usługi bez dbałości o pozostałe połączenia, sugeruję, aby nie używać adnotacji w teście jednostki, aby uprościć test.

Tak więc, moja sugestia jest refaktoryzacji usług, aby otrzymać reszta szablon za pomocą konstruktora wtrysku. Ułatwi to test. Przykład:

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

RestTemplate jako komponentu do wprowadzenia i szydzili po:

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

a test:

public void test() { 

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

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

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

W ten sposób, masz bezpośredni dostęp do mock szablon odpoczynku według konstruktora SomeService.

Powiązane problemy