2016-09-14 3 views
7

Ich habe einen Dienst, bei dem ich einige Informationen einen externen Server über Rest fragen müssen:Wie spotze ich einen REST-Vorlagenaustausch?

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

Wie kann ich einen JUnit-Test für getListofObjectsA() schreiben?

habe ich mit dem unten versucht:

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

jedoch der obige Code, zeigt es nicht funktioniert, dass responseEntittynull ist. Wie kann ich meinen Test korrigieren, um restTemplate.exchange korrekt nachzuahmen?

+1

hat jemand eine idee? –

Antwort

5

Sie benötigen kein MockRestServiceServer Objekt. Die Anmerkung ist @InjectMocks nicht @Inject. Bellow ist ein Beispiel-Code, der

@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

Für mich funktionieren sollte, hatte ich Matchers.any (URI.class) statt

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

ich a small library, die sehr nützlich ist, umgesetzt zu verwenden. Es bietet eine ClientHttpRequestFactory, die einigen Kontext erhalten kann. Auf diese Weise können alle Client-Schichten durchlaufen werden, z. B. die Überprüfung der Abfrageparameter, die Festlegung der Kopfzeilen und die ordnungsgemäße Deserialisierung.

0

Wenn Sie den Service testen möchten, ohne sich um den Restanruf zu kümmern, schlage ich vor, in Ihrem Komponententest keine Anmerkungen zu verwenden, um den Test zu vereinfachen.

Also ist mein Vorschlag Refactor Ihr Service, um die Resttemplate mit Injektion Konstruktor zu erhalten. Dies erleichtert den Test. Beispiel:

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

Die RestTemplate als Komponente, injiziert und nach verspottet werden:

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

und der Test:

public void test() { 

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

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

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

Auf diese Weise haben Sie direkten Zugriff auf die verspotten Rest-Vorlage durch den SomeService-Konstruktor.

Verwandte Themen