cy.intercept란?
cy.intercept는 네트워크 요청(예: XHR, Fetch API, GraphQL 등)을 가로채고 수정하거나, 해당 요청을 대체하여 지정된 데이터를 반환할 수 있도록 해주는 Cypress의 API이다.
주요 기능:
- 네트워크 요청을 모니터링.
- 요청을 차단하거나 수정.
- 특정 요청에 대해 미리 정의된 응답을 제공.
// Specifying request and response types
type CustomRequest = {
kind: 'custom_request'
}
type CustomResponse = {
kind: 'custom_response'
}
cy.intercept<CustomRequest, CustomResponse>(url, (req) => {
req.body // .body of request will be of type CustomRequest
req.continue((res) => {
res.body // .body of request will be of type CustomResponse
})
})
https://docs.cypress.io/api/commands/intercept
intercept | Cypress Documentation
Spy and stub network requests and responses.
docs.cypress.io
- 네트워크 request와 response를 spy 및 stub(mock)할 때 사용한다.
- 진짜 Http response를 변경할 수 있다.
intercept가 작동하는 원리
- 어떤 HTTP request에 대한 stub(mock) 또는 spy 하는 것을 허용하는 것이다.
- 이는 http request의 body, headers 그리고 URL을 변경할 수 있게 된다.
- 예를들어 header를 만들어 보내고 싶을 때 back-end한테 "나 테스트 하고 있어" 이런 식으로 header를 써서 보내도록 설정해줄 수 있다.
- 또는 cypress가 보내는 모든 request는 "테스팅 : true"라는 header와 함께 보내져야 한다고 해줄 수 있다.
cypress를 이용해 request를 가로채는 법
네트워크에서 graphql의 response가 정확하게 어떻게 생겼는지 확인하기
// 실제 graphql response 데이터 값
{
data: {
createAccount: {
ok: false,
error: "이미 해당 이메일을 가진 사용자가 있습니다.",
__typename: "CreateAccountOutput"
}
}
}
localhost:4000/graphql을 Intercept 하기
describe("계정 만들기", () => {
const user = cy;
...
it("계정을 생성하고 로그인해야 합니다.", () => {
// cypress를 이용해 request를 가로채기 (localhost:4000/graphql을 Intercept 하기)
// req를 reply()해서 유저가 데이터베이스에 존재하지 않더라면 일어났을 일을 발생 시키기
user.intercept("<http://localhost:4000/graphql>", (req) => {
req.reply((res) => {
res.send({
data: {
createAccount: {
ok: true,
error: null,
__typename: "CreateAccountOutput"
}
}
});
});
});
// 계정 생성
user.visit("/create-account");
user.findByPlaceholderText("이메일").type("testClient16@mail.com");
user.findByPlaceholderText("비밀번호").type("123123");
user.findByRole("button").click();
// 만든 계정으로 로그인
user.wait(2000);
user.title().should("eq", "로그인 | Nuber Eats");
user.findByPlaceholderText("이메일").type("testClient16@mail.com");
user.findByPlaceholderText("비밀번호").type("123123");
user.findByRole("button").click();
user.window().its("localStorage.nuber-token").should("be.a", "string");
});
});
- 계정 만들기 response를 변경하기
- "유저가 이미 존재합니다"라고 현재 response에서 말해주고 있다.
- response를 수정해서 reactJs가 성공적으로 계정이 생성되었다고 생각하게 만들기
- 이미 존재하는 유저 계정이어도 request를 intercept해서 유저가 실제 존재하는데 존재하지 않은 척하며 create-accout mutation이 통과되어 유저가 이미 존재한다고 뜨지 않게 된다.
에러 발생 : 로그인 graphql 실행이 되지 않고 create-account 부분이 계속 실행되고 있기 때문
request를 intercept 하고 있고있는데 로그인할 때 intercept가 실행되고 있어서 로그인에서 토큰을 받지 못하고 있어 오류가 난다.
특정 graphql만 Intercept 하기
describe("계정 만들기", () => {
const user = cy;
...
it("계정을 생성하고 로그인해야 합니다.", () => {
// cypress를 이용해 request를 가로채기 (localhost:4000/graphql을 Intercept 하기)
user.intercept("<http://localhost:4000/graphql>", (req) => {
const { operationName } = req.body;
if (operationName && operationName === "createAccount") {
req.reply((res) => {
res.send({
data: {
createAccount: {
ok: true,
error: null,
__typename: "CreateAccountOutput"
}
}
});
});
}
});
// 계정 생성
user.visit("/create-account");
user.findByPlaceholderText("이메일").type("testClient16@mail.com");
user.findByPlaceholderText("비밀번호").type("123123");
user.findByRole("button").click();
// 만든 계정으로 로그인
user.wait(2000);
user.title().should("eq", "로그인 | Nuber Eats");
user.findByPlaceholderText("이메일").type("testClient16@mail.com");
user.findByPlaceholderText("비밀번호").type("123123");
user.findByRole("button").click();
user.window().its("localStorage.nuber-token").should("be.a", "string");
});
});
- 만약에 REST로 작업하면 "http:localhost:4000/graphql/login"로 Intercept 하면된다.
- 현재 코드는 Graphql이기 때문에 operationName으로 구분해주면 된다.
'Frontend > Cypress' 카테고리의 다른 글
fixture, 테스트에 사용될 미리 정의된 정적 데이터 파일 (0) | 2024.12.02 |
---|---|
Custom Commands (0) | 2024.12.02 |
Cypress, 브라우저의 localStorage에 저장된 값을 검증하는 코드 테스트 (0) | 2024.11.25 |
Cypress, React Testing Library에서 제공하는 비동기 쿼리 메서드 체인 안되는 부분 해결 방법 (0) | 2024.11.25 |
Cypress testing libray 설치 (0) | 2024.11.14 |