Mocking a RestTemplate in Spring

1. Inleiding

Vaak vinden we onszelf met applicaties die een soort webverzoek uitvoeren. Als het gaat om het testen van dit gedrag, hebben we een paar opties met Spring-apps.

ikIn deze korte handleiding bekijken we slechts een paar manieren om dergelijke oproepen te bespotten die alleen worden uitgevoerd via een RestTemplate.

We gaan testen met Mockito, een populaire spotbibliotheek. Vervolgens gebruiken we Spring Test die ons een mechanisme biedt om een ​​nepserver te maken om de serverinteracties te definiëren.

2. Met behulp van Mockito

We zouden Mockito kunnen gebruiken om het RestTemplate allemaal samen. Met deze aanpak zou het testen van onze service net zo eenvoudig zijn als elke andere test met spot.

Laten we aannemen dat we een simpele hebben Medewerker Service class, die werknemersgegevens ophaalt via HTTP:

@Service openbare klasse EmployeeService {@Autowired privé RestTemplate restTemplate; openbare werknemer getEmployee (String-id) {ResponseEntity resp = restTemplate.getForEntity ("// localhost: 8080 / employee /" + id, Employee.class); return resp.getStatusCode () == HttpStatus.OK? resp.getBody (): null; }} 

Laten we onze test implementeren voor de vorige code:

@RunWith (MockitoJUnitRunner.class) openbare klasse EmployeeServiceTest {@Mock private RestTemplate restTemplate; @InjectMocks private EmployeeService empService = nieuwe EmployeeService (); @Test openbare ongeldig gegevenMockingIsDoneByMockito_whenGetIsCalled_shouldReturnMockedObject () {Werknemer emp = nieuwe werknemer ("E001", "Eric Simmons"); Mockito .when (restTemplate.getForEntity ("// localhost: 8080 / employee / E001", Employee.class)) .thenReturn (nieuwe ResponseEntity (emp, HttpStatus.OK)); Werknemer werknemer = empService.getEmployee (id); Assert.assertEquals (emp, medewerker); }}

In de bovenstaande JUnit-testles hebben we Mockito eerst gevraagd om een ​​dummy te maken RestTemplate instantie met behulp van @Bespotten annotatie.

Vervolgens hebben we de Medewerker Service bijvoorbeeld met @InjectMocks om de dummy-instantie erin te injecteren.

Ten slotte hebben we in de testmethode het gedrag van onze mock gedefinieerd met behulp van Mockito's wanneer / dan-ondersteuning.

3. Met behulp van Spring Test

DeSpring Test-module bevat een nep-server met de naam MockRestServiceServer.Met deze benadering configureren we de server om een ​​bepaald object te retourneren wanneer een specifiek verzoek wordt verzonden via ons RestTemplate voorbeeld. Eindelijk kunnen we verifiëren() op die serverinstantie of aan alle verwachtingen is voldaan of niet.

MockRestServiceServer werkt eigenlijk door de HTTP API-aanroepen te onderscheppen met behulp van een MockClientHttpRequestFactory. Op basis van onze configuratie maakt het een lijst met verwachte verzoeken en bijbehorende antwoorden. Wanneer de RestTemplate instantie roept de API op, zoekt het verzoek op in de lijst met verwachtingen en retourneert het bijbehorende antwoord.

Het elimineert dus de noodzaak om een ​​HTTP-server op een andere poort te draaien voor het verzenden van nepreacties.

Laten we hiervoor een eenvoudige test maken getEmployee () voorbeeld met MockRestServiceServer:

@RunWith (SpringRunner.class) @ContextConfiguration (classes = SpringTestConfig.class) openbare klasse EmployeeServiceMockRestServiceServerUnitTest {@Autowired private EmployeeService empService; @Autowired privé RestTemplate restTemplate; privé MockRestServiceServer mockServer; private ObjectMapper mapper = nieuwe ObjectMapper (); @Before public void init () {mockServer = MockRestServiceServer.createServer (restTemplate); } @Test openbare ongeldig gegevenMockingIsDoneByMockRestServiceServer_whenGetIsCalled_thenReturnsMockedObject () () {Werknemer emp = nieuwe werknemer ("E001", "Eric Simmons"); mockServer.expect (ExpectedCount.once (), requestTo (nieuwe URI ("// localhost: 8080 / employee / E001"))) .andExpect (methode (HttpMethod.GET)) .andRespond (withStatus (HttpStatus.OK) .contentType (MediaType.APPLICATION_JSON) .body (mapper.writeValueAsString (emp))); Werknemer werknemer = empService.getEmployee (id); mockServer.verify (); Assert.assertEquals (emp, medewerker); }} 

In het vorige fragment hebben we statische methoden gebruikt van in MockRestRequestMatchers en MockRestResponseCreators om de verwachting en het antwoord voor de REST-oproep op een duidelijke en leesbare manier te definiëren:

importeer statische org.springframework.test.web.client.match.MockRestRequestMatchers. *; importeer statische org.springframework.test.web.client.response.MockRestResponseCreators. *;

We moeten in gedachten houden dat de RestTemplate in de testklasse moet dezelfde instantie zijn die wordt gebruikt in de Medewerker Service klasse. Om ervoor te zorgen dat we een RestTemplate-bean hebben gedefinieerd in de springconfiguratie en de instantie automatisch hebben bedraad in zowel test als implementatie:

@Bean openbare RestTemplate restTemplate () {retourneer nieuwe RestTemplate (); }

Gebruik maken van een MockRestServiceServer is erg handig wanneer we onze integratietests schrijven en alleen externe HTTP-oproepen hoeven te bespotten.

4. Conclusie

In dit korte artikel hebben we een paar effectieve opties besproken om de externe REST API-aanroepen via HTTP te bespotten tijdens het schrijven van unit-tests.

De broncode voor het bovenstaande artikel is beschikbaar op GitHub.


$config[zx-auto] not found$config[zx-overlay] not found