의존성 추가

dependencies {
		testImplementation 'com.github.tomakehurst:wiremock:2.27.2'
}

https://mvnrepository.com/artifact/com.github.tomakehurst/wiremock/2.27.2

WireMock 을 이용하여 API 기능 테스트

우아한테크코스 레벨3에서 진행한 모모 서비스의 코드를 활용하여 작성해본 테스트 코드이다. 테스트용으로 사용한 기능은 구글 로그인을 하기 위해 진행하는 과정 중 구글 서버로부터 Authorization 코드를 받는 과정이다. 해당 코드를 이용하여 클라이언트가 다시 구글 서버로 재요청하여 구글의 access token 을 발급받을 수 있다.

Authorization 코드를 받는 기능을 테스트하기 위해서(기능 테스트) 구글 서버를 mocking 하였다.

GitHub - woowacourse-teams/2022-momo: 한 눈에 참여하는 모임 서비스, '모두 모여라' 모모입니다.

backend/src/test/java/com/woowacourse/momo/acceptance/auth/OauthAcceptanceTest.java

package com.woowacourse.momo.acceptance.auth;

import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo;
import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.options;

import org.hamcrest.Matchers;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.http.HttpStatus;

import com.github.tomakehurst.wiremock.WireMockServer;
import com.github.tomakehurst.wiremock.client.WireMock;

import io.restassured.RestAssured;
import io.restassured.response.ValidatableResponse;

import com.woowacourse.momo.acceptance.AcceptanceTest;

// AcceptanceTest 는 아래 코드 참고
public class OauthAcceptanceTest extends AcceptanceTest {

    private static final int GOOGLE_PORT = 8089; // mock 서버 포트 정보

    private WireMockServer googleServer;

    @BeforeEach
    void setUp() {
				// mock 서버 생성
        googleServer = new WireMockServer(options().port(GOOGLE_PORT));
        googleServer.start();
    }

    @AfterEach
    void tearDown() {
				// mock 서버 종료
        googleServer.stop();
    }

    @DisplayName("Google 로부터 code 를 받는다")
    @Test
    void generateAuthUrl() {
        // mocking
        String oauthLink = "<https://accounts.google.com/o/oauth2/auth?scope=openid%20https://www.googleapis.com/auth/userinfo.email%20https://www.googleapis.com/auth/userinfo.profile&response_type=code&redirect_uri=https://www.moyeora.com/auth/google&client_id=755121207871-raacm7vn0v386ep86q22kl4s35cvg0io.apps.googleusercontent.com>";
        googleServer.stubFor(WireMock.get(urlEqualTo("/o/oauth2/auth"))
                .willReturn(WireMock.aResponse()
                        .withStatus(HttpStatus.OK.value())
                        .withBody(oauthLink))
        );

        // when & then
        String redirectUrl = "<https://www.moyeora.com/auth/google>";
        URL을_받는다(redirectUrl)
                .statusCode(HttpStatus.OK.value())
                .body("oauthLink", Matchers.equalTo(oauthLink));
    }

    private static ValidatableResponse URL을_받는다(String redirectUrl) {
        return RestAssured.given().log().all()
                .queryParam("redirectUrl", redirectUrl)
                .when()
                .get("/api/auth/oauth2/google/login")
                .then().log().all();
    }
}

외부 서버의 영향을 받지 않고 테스트하기 위해 구글 서버를 mocking 하였다. WireMockServer 를 이용하여 구글 서버를 구축하였다. 테스트 코드를 작성하기 전에 구글 mocking 가 동작해야 하는 과정을 미리 설정해둔다. 해당 과정을 설정하지 않으면 응답은 404 의 null 로 돌아온다.

mocking 서버를 설정해둔뒤 테스트하고 싶은 코드를 작성한다

backend/src/test/java/com/woowacourse/momo/acceptance/AcceptanceTest.java

package com.woowacourse.momo.acceptance;

import static org.springframework.test.context.jdbc.Sql.ExecutionPhase.AFTER_TEST_METHOD;
import static org.springframework.test.context.jdbc.Sql.ExecutionPhase.BEFORE_TEST_METHOD;

import org.junit.jupiter.api.BeforeEach;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.jdbc.Sql;

import io.restassured.RestAssured;

@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@Sql(value = "classpath:init.sql", executionPhase = BEFORE_TEST_METHOD)
@Sql(value = "classpath:truncate.sql", executionPhase = AFTER_TEST_METHOD)
public class AcceptanceTest {

    @Value("${local.server.port}")
    private int port;

    @BeforeEach
    public void init() {
        RestAssured.port = port;
    }
}

모모 어플리케이션(모모 서버)을 구동시키기 위해 @SpringBootTest 에 랜덤포트를 설정해두었다.

@SpringBootTest

Untitled

테스트에서 검증한 값과 실제 구글 서버와 연동한 결과가 일치한 것을 확인할 수 있다.

테스트한 구조를 그림으로 그려보면 다음과 같다.

Untitled

Chapter9. 테스트 범위와 종류