programing

재담을 사용하여 모듈을 조롱하고 함수 호출을 테스트할 수 없습니다.

oldcodes 2023. 2. 28. 23:47
반응형

재담을 사용하여 모듈을 조롱하고 함수 호출을 테스트할 수 없습니다.

create-app-component를 사용하여 프로젝트를 만듭니다.create-app-component는 빌드 스크립트(babel, webpack, jaste)로 새로운 앱을 구성합니다.

테스트하려는 React 컴포넌트를 작성했습니다.컴포넌트에 다른 javascript 파일이 필요하며 함수가 노출됩니다.

내 검색.js 파일

export {
  search,
}

function search(){
  // does things
  return Promise.resolve('foo')
}

내 반응 구성요소:

import React from 'react'
import { search } from './search.js'
import SearchResults from './SearchResults'

export default SearchContainer {
  constructor(){
    this.state = {
      query: "hello world"
    }
  }

  componentDidMount(){
    search(this.state.query)
      .then(result => { this.setState({ result, })})
  }

  render() {
    return <SearchResults 
            result={this.state.result}
            />
  }
}

유닛 테스트에서 방법이search올바른 인수로 호출되었습니다.

제 테스트는 다음과 같습니다.

import React from 'react';
import { shallow } from 'enzyme';
import should from 'should/as-function';

import SearchResults from './SearchResults';

let mockPromise;

jest.mock('./search.js', () => {
  return { search: jest.fn(() => mockPromise)};
});

import SearchContainer from './SearchContainer';

describe('<SearchContainer />', () => {
  it('should call the search module', () => {
    const result = { foo: 'bar' }
    mockPromise = Promise.resolve(result);
    const wrapper = shallow(<SearchContainer />);

    wrapper.instance().componentDidMount();

    mockPromise.then(() => {
      const searchResults = wrapper.find(SearchResults).first();
      should(searchResults.prop('result')).equal(result);
    })    
  })
});

저는 이미 어떻게 해야 할지 고민하고 있었어요.jest.mockwork, 변수 앞에 프레픽스를 붙여야 하기 때문에mock.

그러나 메서드에 대한 인수를 테스트하려면search테스트에서 조롱된 기능을 사용할 수 있도록 해야 합니다.

조롱 부분을 변환하는 경우 변수를 사용하려면:

const mockSearch = jest.fn(() => mockPromise)
jest.mock('./search.js', () => {
  return { search: mockSearch};
});

다음의 에러가 표시됩니다.

TypeError: (0 , _search.search)는 함수가 아닙니다.

제가 어떤 방법으로든jest.fn논쟁을 시험해봐야 소용없어

내가 뭘 잘못하고 있지?

문제

이 오류가 발생하는 이유는 다양한 작업이 어떻게 수행되는지와 관련이 있습니다.

원래 코드에서는 Import만 해도SearchContainer 을 할당한 후mockSearch장난을 치며mock의 사양은 다음과 같습니다.Before instantiating a module, all of the modules it requested must be available.

그래서 그 당시에SearchContainer를 Import하고 다음으로 Import합니다.search ,당신의.mockSearch변수는 아직 정의되지 않았습니다.

이상하다고 생각할 수도 있습니다.그것은 또한 그것이 암시하는 것처럼 보일 수도 있기 때문입니다.search.js아직 조롱당하지 않았으니 조롱은 통하지 않을 겁니다다행히 (babel-jest) jest는 다음 주소로 전화를 건다.mock수입품보다 더 높은 기능을 가지고 있기 때문에 조롱이 통할 것입니다.

그럼에도 불구하고,mockSearch모크 함수에 의해 참조되는, 는, 와 함께 인스톨 되지 않습니다.mock따라서 관련 작업 순서는 다음과 같습니다.

  1. 모의 팩토리 설정./search.js
  2. 모든 종속성을 가져옵니다. 그러면 구성 요소를 제공하는 함수에 대해 모의 팩토리를 호출합니다.
  3. 값 할당 대상mockSearch

스텝 2가 발생하면search컴포넌트에 전달된 함수는 정의되지 않으며 스텝3의 할당이 너무 늦어 변경할 수 없습니다.

솔루션

의 일부로 모의 함수를 만든 경우mockcall(호출도 가능), 초기 예시와 같이 컴포넌트 모듈에 의해 Import될 때 유효한 값이 됩니다.

지적하신 바와 같이, 이 문제는 모의 함수를 테스트에서 사용할 수 있게 하려고 할 때 시작됩니다.여기에는 이미 시뮬레이션한 모듈을 개별적으로 Import하는 확실한 해결책이 하나 있습니다.

수입 전에 실제로 우스갯소리가 발생한다는 것을 알았기 때문에, 간단한 접근법은 다음과 같습니다.

import { search } from './search.js'; // This will actually be the mock

jest.mock('./search.js', () => {
  return { search: jest.fn(() => mockPromise) };
});

[...]

beforeEach(() => {
  search.mockClear();
});

it('should call the search module', () => {
  [...]

  expect(search.mock.calls.length).toBe(1);
  expect(search.mock.calls[0]).toEqual(expectedArgs);
});

실제로 다음 항목을 대체할 수 있습니다.

import { search } from './search.js';

포함:

const { search } = require.requireMock('./search.js');

에 의해,더할 수 의 타입 하고 있는 될입니다).생각되지 않습니다.따라서 당신이 원래 함수에 모크 함수를 호출하려고 하지 않는다고 생각한다.search를 참조해 주세요.

추가 메모

이 모든 것이 필요한 것은 모듈 자체의 디폴트내보내기일 경우뿐입니다.그렇지 않으면(@publicJorn이 지적한 바와 같이) 다음과 같이 테스트에서 특정 관련 멤버를 재할당하기만 하면 됩니다.

import * as search from './search.js';

beforeEach(() => {
  search.search = jest.fn(() => mockPromise);
});

저의 경우, 모크를 올바르게 구현하지 못했기 때문에 이 오류가 발생하였습니다.

실패 코드:

jest.mock('react-native-some-module', mockedModule);

화살표 기능이어야 할 때...

jest.mock('react-native-some-module', () => mockedModule);

응답으로 API 콜을 조롱할 경우 async() = > 테스트에 접속하여 래퍼 업데이트를 기다립니다.일반적인 componentDidMount = > API 호출 = > positive response set some state...그러나 래퍼의 상태가 업데이트되지 않았습니다...비동기화 및 수정 대기...이 예는 간결하게 하기 위한 것이다...

...otherImports etc...
const SomeApi = require.requireMock('../../api/someApi.js');

jest.mock('../../api/someApi.js', () => {
    return {
        GetSomeData: jest.fn()
    };
});

beforeEach(() => {
    // Clear any calls to the mocks.
    SomeApi.GetSomeData.mockClear();
});

it("renders valid token", async () => {
        const responseValue = {data:{ 
            tokenIsValid:true}};
        SomeApi.GetSomeData.mockResolvedValue(responseValue);
        let wrapper = shallow(<MyPage {...props} />);
        expect(wrapper).not.toBeNull();
        await wrapper.update();
        const state = wrapper.instance().state;
        expect(state.tokenIsValid).toBe(true);

    });

언급URL : https://stackoverflow.com/questions/39633919/cannot-mock-a-module-with-jest-and-test-function-calls

반응형