React에서 테스트를 위한 HTTP 시뮬레이션

따라와, 주제나 개선에 대한 당신의 건의를 들으니 기쁩니다/Chris

Nock is used to mocking calls to HTTP. It makes it possible for us to specify what URLs to listen to and what to respond with. This is a fairly short article that shows how you use the library nock.



이 문서에서는 다음과 같이 설명합니다.

  • nock 설정, 아날로그 응답 지정

  • 조회 매개 변수, 조회 매개 변수를 사용하여 nock
  • 을 설정하는 방법 보기

  • 검증, 우리는 우리의 nocks가 맞았는지 시종일관 검증해야 한다.만약 그것들이 변하지 않는다면, 우리는 우리의 테스트를 바꾸어 이 점을 반영해야 한다
  • HTTP를 에뮬레이션하는 이유는 무엇입니까?


    우리가 단독으로 해야 할 일을 테스트할 때, 우리는 현재 우리가 있는 모듈만 테스트하는 데 집중해야 한다.이것은 우리가 외부 의존에 대한 어떤 시뮬레이션에 의존해야 한다는 것을 의미한다.외부 의존 관계뿐만 아니라 HTTP 호출 등 사용자가 제어할 수 없는 모든 외부 부작용에도 적용됩니다.HTTP 호출을 실제로 통과하는 데는 많은 문제가 있을 수 있습니다. 예를 들어 연결성과 속도 제한, 최종적으로 테스트 범위를 초과한 내용을 테스트할 수 있습니다.이 문서의 해결 방안은 라이브러리 Nock을 사용하는 것입니다.

    스크립트


    다음 장면에서 우리는 제품 목록을 표시해야 하는 구성 요소를 어떻게 테스트하는지 연구할 것이다.목록 데이터는 HTTP에서 호출됩니다.
    이 장면을 실행할 수 있도록 먼저 React를 만들어야 합니다.js 프로젝트.CRA-Create React 응용 프로그램을 실행하는 것이 가장 쉽습니다.그럼 우리 먼저 이렇게 합시다.

    npx create-react-app my-app


    일단 프로젝트가 생기면 테스트 장면과 Nock 테스트에 필요한 파일을 토론해 봅시다.
    다음과 같은 파일이 있다고 가정합니다.

  • 제품js, 우리를 위해 데이터를 검색할 수 있는 서비스

  • 제품 목록.js, 제품에 호출하는 방법의 구성 요소입니다.js 데이터 가져오기 및 렌더링
  • 이 두 모듈이 어떤 모양인지 살펴보겠습니다.
    // products.js
    export const getProducts = async () => { 
      const response = await fetch('http://myapi.com/products'); 
      const json = await response.json(); 
      console.log(json);
      return json.products; 
    }
    
    위에서 알 수 있듯이 우리는 URLfetch()을 호출한 다음에 응답을 변환하고 데이터 제품을 발굴했다.구성 요소를 살펴보겠습니다.
    // ProductsList.js
    import React from 'react'; 
    import { getProducts } from '../products'; 
    const Products = ({ products }) => ( 
      <React.Fragment> 
      {products.map(p => <div>{product.name}</div>)} 
     </React.Fragment> 
    ); 
    
    class ProductsContainer extends React.Component { 
      state = { products: undefined, }
    
      async componentDidMount() { 
        const products = await getProducts(); 
        this.setState({ products }); 
      } 
    
      render() { 
       if (!this.state.products) return null;
       else return ( <Products products={this.state.products} /> ); 
      } 
    }
    
    export default ProductsContainer;
    
    우리는 우리가 제품을 사용하는 것을 볼 수 있다.js모듈을 http://myapi.com/products에서 호출getProducts()하고 마지막으로 데이터가 도착할 때 데이터를 보여줍니다.

    테스트


    만약 우리가 componentDidMount() 모듈을 테스트하고 싶다면, 우리는 모방 제품에 중점을 둘 것이다.일종의 의존이기 때문이다.우리는 도서관의 nock으로 이것을 할 수 있다.
    다음과 같이 nock 설치를 시작합니다.

    yarn add nock


    이제 테스트ProductsList.js를 작성하여 다음과 같이 정의합니다.
    // __tests__/ProductsList.spec.js
    import React from 'react'; 
    import ReactDOM from 'react-dom'; 
    import ProductsList from '../ProductsList'; 
    import nock from 'nock'; 
    
    it('renders without crashing', () => { 
      const div = document.createElement('div');
      ReactDOM.render(<ProductsList />, div);
      ReactDOM.unmountComponentAtNode(div); 
    });
    
    설정하지 않으면 __tests__/ProductsList.spec.js 무슨 일이 일어날지 먼저 봅시다.
    우리는 다음과 같은 결론을 얻었다.

    위에서 보듯이 네트워크 요청을 실행하려고 합니다.테스트를 실행할 때, 우리는 영원히 이렇게 해서는 안 된다.우리는 이를 위해 nock 시뮬레이션을 추가할 수 있다. 이것은 반드시 그것을 해결하는 방법이다. 그리고 이것은 다음과 같다.
    // __mocks__/products.js
    export const getProducts = async () => { 
      const products = await Promise.resolve([{ name: 'test' }]); 
      return products; 
    }
    
    이것은 가능하지만, 어떻게 nock으로 이 문제를 해결하는지 봅시다.노드 환경에서 호출하려고 하기 때문에 Jest 이 제대로 설정되었는지 확인해야 합니다.제안은 글로벌 파트너십을 구축하는 것입니다.다음과 같이 노드 가져오기를 할당합니다.
    global.fetch = require('node-fetch');
    
    이제 다음과 같이 nock을 테스트에 추가합니다.
    import React from 'react'; 
    import ReactDOM from 'react-dom'; 
    import ProductsList from '../ProductsList'; 
    import nock from 'nock'; 
    
    it('renders without crashing', () => { 
       const scope = nock('http://myapi.com') 
       .get('/products')
       .reply(200, { products: [{ id: 1, name: 'nocked data' }] }, 
       { 
         'Access-Control-Allow-Origin': '*', 
         'Content-type': 'application/json' 
       }); 
       const div = document.createElement('div');
       ReactDOM.render(<ProductsList />, div);
       ReactDOM.unmountComponentAtNode(div); 
    });
    
    위에서 우리가 fetch() 방법을 어떻게 호출하는지 주의하십시오. 우선 그것nock()baseUrl, 그 다음에 경로http://myapi.com와 HTTP 동사 get, 그리고 우리가 어떻게 /products의 응답을 정의하는지 주의하십시오.우리는 또한 reply() 방법에 두 번째 파라미터를 제공하여 reply()가 역할을 잘 발휘할 수 있도록 확보하였다.이 점에서 우리의 테스트 작업은 다음과 같다.

    모든 것이 정상적입니다. 우리는 nock을 사용하여 HTTP 호출을 시뮬레이션했습니다. 

    처리 질의 매개변수를 사용합니다.질의 ()


    만약 우리가 이런 URL을 가지고 있다면:CORS ;
    우리는 어떻게 nock을 설정하여 그것과 일치합니까?다음과 같이 helper 방법으로 조회할 수 있습니다.
    nock('http://myapi.com') 
    .get('/products') 
    .query({ page: 1, pageSize: 10 })
    

    시뮬레이션 확인


    가장 좋은 방법은 당신이 설정한 시뮬레이션이 맞았는지 확인하는 것입니다.이를 위해, 우리가 이렇게 nock를 호출할 때, 되돌아오는 인용 호출 http://myapi.com/products?page=1&pageSize=10:
    const scope = nock('http://myapi.com') 
      .get('/products') 
      .reply(
        200, 
        { products: [{ id: 1, name: 'nocked data' }] }, 
        { 
          'Access-Control-Allow-Origin': '*', 
          'Content-type': 'application/json' 
        }
    ); 
    scope.done();
    
    그렇다면 우리가 시뮬레이션 모형을 세울 때 그것이 아닌 시뮬레이션 모형을 세울 때 무슨 일이 일어날까?그러면 다음과 같이 테스트에 다른 호출을 추가합니다.
    const users = nock('http://myapi.com') 
      .get('/users') 
      .reply(
        200, 
        { products: [{ id: 1, name: 'user' }] }, 
        { 
          'Access-Control-Allow-Origin': '*', 
          'Content-type': 'application/json' 
        }
    );
    
    지금 보아하니 이렇다.

    HTTP 호출 차단


    HTTP 호출이 실제로 이루어지지 않도록 하려면 이 기능을 종료해야 합니다.우리는 done()에 다음 줄을 추가하여 실현할 수 있다.
    import nock from 'nock'; 
    nock.disableNetConnect();
    
    우리는 노크가 무엇인지, 그리고 어떻게 서로 다른 상황에서 그것을 사용하는지 간략하게 설명했다.이것은 단지 많은 HTTP 호출을 처리하는 방법 중의 하나일 뿐이다.
    너는 노크로 더 많은 일을 할 수 있다. 우리는 거의 표면에 닿지 않았다.공식 문서 보기 Nock 문서

    총결산


    알겠습니다. HTPP를 통해 발생하는 모든 호출을 차단하는 것이 왜 좋은 생각인지 초보적으로 토론했습니다.우리는 이미 일반적인 시뮬레이션을 사용하여 이 점을 실현할 수 있다고 언급했지만, 우리는 라이브러리 시뮬레이션을 사용하여 금속에 더욱 가까운 방법을 시뮬레이션했다.노크를 사용하기 시작하는 것이 얼마나 쉬운지 보셨으면 좋겠습니다.
    따라와, 주제나 개선에 대한 당신의 건의를 들으니 기쁩니다/Chris

    좋은 웹페이지 즐겨찾기