[Cypress] API Mocking 하기
Cypress로 테스트하다 보면, API를 Mocking하여 처리해야할 일이 생긴다.
다음과 같은 이유가 있다.
1. public api 를 이용할 때는 할당량이 있는 경우가 있어서, 테스트에 할당량을 낭비하지 않기 위해서
2. private api의 경우에도 서버 비용이 발생하기 때문에
Cypress는 공식 문서가 매우 잘 돼있기 때문에, 가급적 공식문서 읽기를 추천한다.
API Mocking은 특히 intercept 개념을 읽으면 된다.
https://docs.cypress.io/api/commands/intercept
intercept | Cypress Documentation
Spy and stub network requests and responses. Tip: We recommend you read the Network Requests guide first. cy.intercept() is the successor to cy.route()
docs.cypress.io
나에게 주어진 상황은 다음과 같다.
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 한다.