[Java Spring JWT] JWT unit testing
阿新 • • 發佈:2020-12-28
Testing JWT proteceted endpoint:
/** * HTTP POST /tours/{tourId}/ratings */ @Test public void createTourRating() throws Exception { restTemplate.exchange(TOUR_RATINGS_URL, POST, new HttpEntity(ratingDto, jwtRequestHelper.withRole("ROLE_CSR")), Void.class); verify(this.serviceMock).createNew(TOUR_ID, CUSTOMER_ID, SCORE, COMMENT); }
package com.example.ec.web; import com.example.ec.domain.Role; import com.example.ec.security.JwtProvider; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpHeaders;import org.springframework.stereotype.Component; import java.util.Arrays; import static org.springframework.http.MediaType.APPLICATION_JSON; /** * Helper class for creating HTTP Headers before invoking an API with TestRestClient. */ @Component public class JwtRequestHelper { @Autowired privateJwtProvider jwtProvider; /** * Generate the appropriate headers for JWT Authentication. * * @param roleName role identifier * @return Http Headers for Content-Type and Authorization */ public HttpHeaders withRole(String roleName){ HttpHeaders headers = new HttpHeaders(); Role r = new Role(); r.setRoleName(roleName); String token = jwtProvider.createToken("anonymous", Arrays.asList(r)); headers.setContentType(APPLICATION_JSON); headers.add("Authorization", "Bearer " + token); return headers; } }
--
package com.example.ec.web; import com.example.ec.domain.Tour; import com.example.ec.domain.TourRating; import com.example.ec.service.TourRatingService; import org.junit.Before; import org.junit.Ignore; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.boot.test.web.client.TestRestTemplate; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageImpl; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Pageable; import org.springframework.http.HttpEntity; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.test.context.junit4.SpringRunner; import java.util.Arrays; import java.util.List; import static org.hamcrest.core.Is.is; import static org.junit.Assert.assertThat; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; import static org.springframework.http.HttpMethod.*; /** * * Invoke the Controller methods via HTTP. * Do not invoke the tourRatingService methods, use Mock instead * Created by Mary Ellen Bowman. */ @RunWith(SpringRunner.class) @SpringBootTest(webEnvironment = RANDOM_PORT) public class TourRatingControllerTest { //These Tour and rating id's do not already exist in the db private static final int TOUR_ID = 999; private static final int CUSTOMER_ID = 1000; private static final int SCORE = 3; private static final String COMMENT = "comment"; private static final String TOUR_RATINGS_URL = "/tours/" + TOUR_ID + "/ratings"; @Autowired private TestRestTemplate restTemplate; @Autowired private JwtRequestHelper jwtRequestHelper; @MockBean private TourRatingService serviceMock; @Mock private TourRating tourRatingMock; @Mock private Tour tourMock; private RatingDto ratingDto = new RatingDto(SCORE, COMMENT,CUSTOMER_ID); @Before public void setupReturnValuesOfMockMethods() { when(tourRatingMock.getComment()).thenReturn(COMMENT); when(tourRatingMock.getScore()).thenReturn(SCORE); when(tourRatingMock.getCustomerId()).thenReturn(CUSTOMER_ID); when(tourRatingMock.getTour()).thenReturn(tourMock); when(tourMock.getId()).thenReturn(TOUR_ID); } /** * HTTP POST /tours/{tourId}/ratings */ @Test public void createTourRating() throws Exception { restTemplate.exchange(TOUR_RATINGS_URL, POST, new HttpEntity(ratingDto, jwtRequestHelper.withRole("ROLE_CSR")), Void.class); verify(this.serviceMock).createNew(TOUR_ID, CUSTOMER_ID, SCORE, COMMENT); } /** * HTTP DELETE /tours/{tourId}/ratings */ @Test public void delete() throws Exception { restTemplate.exchange(TOUR_RATINGS_URL + "/" + CUSTOMER_ID, DELETE, new HttpEntity(jwtRequestHelper.withRole("ROLE_CSR")), Void.class); verify(serviceMock).delete(TOUR_ID, CUSTOMER_ID); } /** * HTTP POST /tours/{tourId}/ratings/{score}?customers={ids..} */ @Test public void createManyTourRatings() throws Exception { restTemplate.exchange(TOUR_RATINGS_URL + "/" + SCORE + "?customers=" + CUSTOMER_ID, POST, new HttpEntity(ratingDto, jwtRequestHelper.withRole("ROLE_CSR")), Void.class); verify(serviceMock).rateMany(TOUR_ID, SCORE, new Integer[] {CUSTOMER_ID}); } /** * HTTP GET /tours/{tourId}/ratings */ @Test public void getAllRatingsForTour() throws Exception { List<TourRating> listOfTourRatings = Arrays.asList(tourRatingMock); Page<TourRating> page = new PageImpl(listOfTourRatings, PageRequest.of(0,10),1); when(serviceMock.lookupRatings(anyInt(),any(Pageable.class))).thenReturn(page); ResponseEntity<String> response = restTemplate.getForEntity(TOUR_RATINGS_URL,String.class); assertThat(response.getStatusCode(), is(HttpStatus.OK)); verify(serviceMock).lookupRatings(anyInt(), any(Pageable.class)); } /** * HTTP GET /tours/{tourId}/ratings/average */ @Test public void getAverage() throws Exception { when(serviceMock.getAverageScore(TOUR_ID)).thenReturn(3.2); ResponseEntity<String> response = restTemplate.getForEntity(TOUR_RATINGS_URL + "/average", String.class); assertThat(response.getStatusCode(), is(HttpStatus.OK)); assertThat(response.getBody(), is("{\"average\":3.2}")); } /** * HTTP PUT /tours/{tourId}/ratings */ @Test public void updateWithPut() throws Exception { when(serviceMock.update(TOUR_ID, CUSTOMER_ID, SCORE, COMMENT)).thenReturn(tourRatingMock); restTemplate.exchange(TOUR_RATINGS_URL, PUT, new HttpEntity(ratingDto, jwtRequestHelper.withRole("ROLE_CSR")), Void.class); verify(serviceMock).update(TOUR_ID, CUSTOMER_ID, SCORE, COMMENT); } /** * HTTP PATCH /tours/{tourId}/ratings */ /** * RestTemplate Patch only works if it uses httpclient. Method will only work if: * 1. Include dependency * <dependency> * <groupId>org.apache.httpcomponents</groupId> * <artifactId>httpclient</artifactId> * <version>4.4.1</version> * </dependency> * 2. Attach httpclient * restTemplate.getRestTemplate().setRequestFactory(new HttpComponentsClientHttpRequestFactory()); */ @Test @Ignore public void updateWithPatch() { when(serviceMock.updateSome(TOUR_ID, CUSTOMER_ID, SCORE, COMMENT)).thenReturn(tourRatingMock); restTemplate.exchange(TOUR_RATINGS_URL, PATCH, new HttpEntity(ratingDto, jwtRequestHelper.withRole("ROLE_CSR")), Void.class); verify(serviceMock).updateSome(TOUR_ID, CUSTOMER_ID, SCORE, COMMENT); } }