Cypress로 테스트하다 보면, API를 Mocking하여 처리해야할 일이 생긴다.
다음과 같은 이유가 있다.
1. public api 를 이용할 때는 할당량이 있는 경우가 있어서, 테스트에 할당량을 낭비하지 않기 위해서
2. private api의 경우에도 서버 비용이 발생하기 때문에
Cypress는 공식 문서가 매우 잘 돼있기 때문에, 가급적 공식문서 읽기를 추천한다.
API Mocking은 특히 intercept 개념을 읽으면 된다.
https://docs.cypress.io/api/commands/intercept
나에게 주어진 상황은 다음과 같다.
1. 유튜브 API 를 이용 중이다.
2. 검색 키를 누르면, Search를 진행하고, 10개의 data 를 fetch 한다.
3. #search-input-keyword 가 submit 되면, fetch를 실행하여 뷰를 렌더링 하는 구조이다.
4. 10개의 영상 데이터가 정상적으로 화면에 보여지는지 테스트한다.
API Mocking에는 intercept 개념이 사용된다.
이는 특정 method, url, query 일 때 spying하거나, reponse를 stubbing(mocking)하는 데 쓰인다.
// spying only
cy.intercept(url)
cy.intercept(method, url)
cy.intercept(routeMatcher)
// spying and response stubbing
cy.intercept(url, staticResponse)
cy.intercept(method, url, staticResponse)
cy.intercept(routeMatcher, staticResponse)
cy.intercept(url, routeMatcher, staticResponse)
spying만 하기 위해서는 위의 방식으로 사용하고, reponse를 받아야 한다면 밑의 방식을 이용하자.
나 같은 경우는 유튜브 영상 데이터를 reponse로 받아야하기 때문에, 밑의 방식을 이용했다.
그 중에서 3번째인 방식인 routeMatcher를 이용한 방식으로 테스트했다.
어떻게 사용하는지 보자.
import { BASE_URL, OPTIONS } from '../../src/js/api/api';
describe('유튜브 App 테스트', () => {
beforeEach(() => { // 모든 테스트 이전에 실행할 코드
cy.intercept(
{
url: BASE_URL + '*', // BASE_URL에
query: { // query가 다음과 같을 때
part: 'snippet',
type: 'video',
maxResults: `${LOAD_VIDEOS_COUNT}`,
q: '우테코',
},
},
{ fixture: 'searchResult.json' } // 이를 reponse 한다.
);
cy.visit('http://localhost:8080/');
});
it('검색을 하면(enter), 10개의 영상 데이터를 받아와서, 화면에 보여준다.', () => {
cy.get('#search-modal-button').click();
cy.get('#search-input-keyword')
.type('우테코{enter}') // enter를 누르면 submit되고, 위에서 mocking한 데이터를 받아올 것이다.
.then(() => {
cy.get('#video-list .video-card.real').should(
'have.length',
LOAD_VIDEOS_COUNT
);
$$('#video-list .video-item__title').forEach(el =>
cy.get(el).should('have.text')
);
});
});
}
위 inercept 문을 해석하면 다음과 같다.
url이 BASE_URL이며, query가 다음과 같을 때, 그 api는 fixtures에 있는 searchResult.json 파일을 반환한다.
(fixture는 고정물되어 있는 물체를 말하며, 위의 staticResponse와 상응하는 의미이다.)
fixtures 폴더 안에 searchResult.json을 넣어두고, json 형식으로 정의해놓았다면, import/export 하지 않아도 해당 값을 reponse 한다.
'Sofeware Development' 카테고리의 다른 글
[React] Batching을 활용한 렌더링 최적화 (0) | 2022.05.20 |
---|---|
[React] 함수형 컴포넌트는 왜 이벤트 부착 시점의 상태를 기억할까? (2) | 2022.05.03 |
TypeScript 레벨업 하기(feat. Utility Type 분석) (0) | 2022.04.08 |
[JavaScript] 웹 컴포넌트에 Observer Pattern을 적용하여 상태관리하기 (1) | 2022.03.14 |
JavaScript로 추상 클래스, 추상 메소드를 구현하기 (0) | 2022.03.04 |