source

리액트 리덕스 접속 컴포넌트를 유닛 테스트하는 방법

nicesource 2023. 3. 20. 23:19
반응형

리액트 리덕스 접속 컴포넌트를 유닛 테스트하는 방법

유닛 테스트에는 Mocha, Chai, Karma, Sinon, Webpack을 사용하고 있습니다.

이 링크를 따라 리액트 리듀스 코드의 테스트 환경을 설정했습니다.

Karma, Babel 및 Webpack을 사용한 React에서 테스트와 코드 적용 범위를 구현하는 방법

액션과 리듀서 javascript 코드는 정상적으로 테스트할 수 있지만 컴포넌트 테스트에서는 항상 오류가 발생합니다.

import React from 'react';
import TestUtils from 'react/lib/ReactTestUtils'; //I like using the Test Utils, but you can just use the DOM API instead.
import chai from 'chai';
// import sinon from 'sinon';
import spies from 'chai-spies';

chai.use(spies);

let should = chai.should()
  , expect = chai.expect;

import { PhoneVerification } from '../PhoneVerification';

let fakeStore = {
      'isFetching': false,
      'usernameSettings': {
        'errors': {},
        'username': 'sahil',
        'isEditable': false
      },
      'emailSettings': {
        'email': 'test@test.com',
        'isEmailVerified': false,
        'isEditable': false
      },
      'passwordSettings': {
        'errors': {},
        'password': 'showsomestarz',
        'isEditable': false
      },
      'phoneSettings': {
        'isEditable': false,
        'errors': {},
        'otp': null,
        'isOTPSent': false,
        'isOTPReSent': false,
        'isShowMissedCallNumber': false,
        'isShowMissedCallVerificationLink': false,
        'missedCallNumber': null,
        'timeLeftToVerify': null,
        '_verifiedNumber': null,
        'timers': [],
        'phone': '',
        'isPhoneVerified': false
      }
}

function setup () {
    console.log(PhoneVerification);
    // PhoneVerification.componentDidMount = chai.spy();
    let output = TestUtils.renderIntoDocument(<PhoneVerification {...fakeStore}/>);
    return {
        output
    }
}

describe('PhoneVerificationComponent', () => {
    it('should render properly', (done) => {
        const { output } = setup();
        expect(PhoneVerification.prototype.componentDidMount).to.have.been.called;
        done();
    })
});

이 에러는, 상기의 코드로 표시됩니다.

FAILED TESTS:
  PhoneVerificationComponent
    ✖ should render properly
      Chrome 48.0.2564 (Mac OS X 10.11.3)
    Error: Invariant Violation: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: undefined.

스파이에서 차이 스파이로 전환해봤어

리액트 리덕스 연결 구성 요소(스마트 구성 요소)를 테스트하려면 어떻게 해야 합니까?

이를 위해서는 플레인컴포넌트와 컴포넌트를 모두 내보내는 것이 좋습니다.이름 있는 내보내기는 컴포넌트가 됩니다.기본값은 랩된 컴포넌트입니다.

export class Sample extends Component {

    render() {
        let { verification } = this.props;
        return (
            <h3>This is my awesome component.</h3>
        );
    }

}

const select = (state) => {
    return {
        verification: state.verification
    }
}

export default connect(select)(Sample);

앱에서 수 에서는 Import를 사용하여 이름 수 .import { Sample } from 'component'.

수용된 답변의 문제는 테스트만 하기 위해 불필요하게 수출하고 있다는 것입니다.그리고 단지 테스트하기 위해 수업을 내보내는 것은 좋은 생각이 아니라고 생각합니다.

다음은 연결된 컴포넌트를 제외한 다른 것을 내보낼 필요가 없는 보다 깔끔한 솔루션입니다.

할 수 .connect다음과 같이 합니다.

  1. 맵스테이트토프롭
  2. map Dispatch To Props
  3. 리액트 컴포넌트

그렇게 하는 것은 매우 간단합니다.두 가지 방법이 있습니다.인라인 모크 또는 글로벌모크

1. 인라인 모의 사용

테스트 설명 함수 앞에 다음 스니펫을 추가합니다.

jest.mock('react-redux', () => {
  return {
    connect: (mapStateToProps, mapDispatchToProps) => (ReactComponent) => ({
      mapStateToProps,
      mapDispatchToProps,
      ReactComponent
    }),
    Provider: ({ children }) => children
  }
})

2. 파일 모의 사용

  1. " " " 를 만듭니다.__mocks__/react-redux.js루트(패키지).json이 있습니다.)
  2. 다음 스니펫을 파일에 추가합니다.

module.exports = {
  connect: (mapStateToProps, mapDispatchToProps) => (ReactComponent) => ({
    mapStateToProps,
    mapDispatchToProps,
    ReactComponent,
  }),
  Provider: ({children}) => children
};

하고 의 세 할 수 .Container.mapStateToProps ,Container.mapDispatchToProps ★★★★★★★★★★★★★★★★★」Container.ReactComponent

컨테이너를 Import하려면

import Container from '<path>/<fileName>.container.js'

도움이 됐으면 좋겠다.

파일 모크를 사용하는 경우는, 주의해 주세요.은 모든 케이스에 됩니다(「」를 사용하지 않는 한).jest.unmock('react-redux'))테스트 케이스 전에

편집: 상기의 내용을 상세하게 설명하는 블로그를 작성했습니다.

http://rahulgaba.com/front-end/2018/10/19/unit-testing-redux-containers-the-better-way-using-jest.html

접속되어 있는 컴포넌트를 테스트할 수 있으므로 테스트하는 것이 좋다고 생각합니다.먼저 연결되지 않은 컴포넌트를 테스트하고 싶을 수도 있지만, 연결된 컴포넌트를 테스트하지 않고는 완전한 테스트를 할 수 없습니다.

아래는 레독스와 효소로 무엇을 하는지 테스트되지 않은 추출물입니다.중심 아이디어는 Provider를 사용하여 테스트 중인 상태를 테스트 중인 연결 구성 요소에 연결하는 것입니다.

import { Provider } from 'react-redux';
import configureMockStore from 'redux-mock-store';
import SongForm from '../SongForm'; // import the CONNECTED component

// Use the same middlewares you use with Redux's applyMiddleware
const mockStore = configureMockStore([ /* middlewares */ ]);
// Setup the entire state, not just the part Redux passes to the connected component.
const mockStoreInitialized = mockStore({ 
    songs: { 
        songsList: {
            songs: {
                songTags: { /* ... */ } 
            }
        }
    }
}); 

const nullFcn1 = () => null;
const nullFcn2 = () => null;
const nullFcn3 = () => null;

const wrapper = mount( // enzyme
        <Provider store={store}>
          <SongForm
            screen="add"
            disabled={false}
            handleFormSubmit={nullFcn1}
            handleModifySong={nullFcn2}
            handleDeleteSong={nullFcn3}
          />
        </Provider>
      );

const formPropsFromReduxForm = wrapper.find(SongForm).props(); // enzyme
expect(
        formPropsFromReduxForm
      ).to.be.deep.equal({
        screen: 'add',
        songTags: initialSongTags,
        disabled: false,
        handleFormSubmit: nullFcn1,
        handleModifySong: nullFcn2,
        handleDeleteSong: nullFcn3,
      });

===== ../SongForm.js

import React from 'react';
import { connect } from 'react-redux';

const SongForm = (/* object */ props) /* ReactNode */ => {
    /* ... */
    return (
        <form onSubmit={handleSubmit(handleFormSubmit)}>
            ....
        </form>

};

const mapStateToProps = (/* object */ state) /* object */ => ({
    songTags: state.songs.songTags
});
const mapDispatchToProps = () /* object..function */ => ({ /* ... */ });

export default connect(mapStateToProps, mapDispatchToProps)(SongForm)

순수 Redux로 스토어를 만드는 것이 좋습니다.redux-mock-store는 테스트용 경량 버전입니다.

에어비앤비의 효소 대신 리액트 애드온 테스트 효용을 사용하는 것이 좋습니다.

Airbnb의 chai-enzyme을 사용하여 React-aware 기대 옵션을 제공합니다.이 예에서는 필요하지 않습니다.

redex-connected 컴포넌트를 반응으로 테스트하기 위한 훌륭한 툴입니다.

const containerElement = shallow((<Provider store={store}><ContainerElement /></Provider>));

가짜 스토어를 생성하여 컴포넌트를 마운트합니다.

문서 "Testing redux store connected React Components | Jest and Enze | TDD | RECT | RECT Native" (제스트와 효소를 사용하여 연결된 리액트 컴포넌트를 저장합니다)를 참조하십시오.

여기에 이미지 설명 입력

2개의 파일(하나는 컴포넌트 자체 포함)을 작성합니다(PhoneVerification-component.js).다음으로 어플리케이션에서 사용하는두 번째 컴포넌트(PhoneVerification.js).이 컴포넌트에서는 첫 번째 컴포넌트만 반환됩니다.connect기능 같은 것

import PhoneVerificationComponent from './PhoneVerification-component.js'
import {connect} from 'react-redux'
...
export default connect(mapStateToProps, mapDispatchToProps)(PhoneVerificationComponent)

그런 다음 "덤" 컴포넌트를 테스트하려면PhoneVerification-component.js필요한 조롱의 소품들을 제공하는 것 뿐이죠이미 테스트된 테스트 포인트는 없습니다(접속 데코레이터, mapStateToProps, mapDispatchToProps 등).

언급URL : https://stackoverflow.com/questions/35131312/how-to-unit-test-react-redux-connected-components

반응형