0

我必须测试以下组件:

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

import { open as openModal } from 'redux/actions/ModalActions';
import { MODAL_CONTENT_ADD_TO_ALBUM } from 'constants/ModalNameConstants';

import ContentAddToAlbumModal from 'components/ContentAddToAlbumModal';
import AddSection from 'components/AddSection';

export function AddToAlbumButton(props) {
  const { openUploadModal } = props;

  return (
    <>
      <div>
        <div>
          <AddSection
            onClick={openUploadModal}
          />
        </div>
      </div>
      <ContentAddToAlbumModal/>
    </>
  );
}

function mapDispatchToProps(dispatch, props) {
  return {
    openUploadModal() {
      return dispatch(
        openModal(MODAL_CONTENT_ADD_TO_ALBUM, props.content.get('id'))
      );
    },
  };
}

export default connect(null, mapDispatchToProps)(AddToAlbumButton);

我写了我的测试用例如下:

import React from 'react';
import {render} from '@testing-library/react';
import {AddToAlbumButton} from 'components/AddToAlbumButton';

jest.mock('components/ContentAddToAlbumModal', () => {
  return function ContentAddToAlbumModal() {
      return (
      <div>
          ContentAddToAlbumModal
      </div>
      )
  };
});

jest.mock('components/AddSection', () => {
  return function AddSection({openUploadModal}) {
      return (
      <div onClick={openUploadModal}>
          AddSection
      </div>
      )
  };
});


describe('AddToAlbumButton component', () => {

  const props = {
    openUploadModal: jest.fn()
  };

  it('Should render snapshot of AddToAlbumButton component correctly', () => {
    const {asFragment} = render(<AddToAlbumButton {...props} />);    
    expect(asFragment()).toMatchSnapshot();
  })
});

我也想测试我的 mapDispatchToProps 函数,如何在不公开导出的情况下测试它。我应该如何测试连接的组件?

我在网上寻找建议。我发现的一个方法是通过在 jest 目录的mocks文件夹中创建一个文件来模拟“react-redux”模块,代码片段如下:

const mockDispatch = jest.fn(action => action);
module.exports = {
    connect: (mapStateToProps, mapDispatchToProps) => reactComponent => ({
        mapStateToProps,
        mapDispatchToProps: (dispatch = mockDispatch, ownProps) => (
            mapDispatchToProps(dispatch, ownProps)
        ),
        [reactComponent.displayName || reactComponent.name || 'reactComponent']: reactComponent,
        mockDispatch,
    }),
    Provider: ({ children }) => children,
};

我应该如何将上面的代码片段与“反应测试库”一起使用。我的测试用例缺少什么?我应该如何进行?

谢谢

4

1 回答 1

0

您可以使用redux-mock-store包来创建模拟商店。Provider用这个模拟商店包装你的组件。

您可以通过调用获取所有操作store.getActions()。最后,您可以使用任何断言库来测试有效负载。

这种测试方法更接近于集成测试,集成 React 组件connect,和mapDispatchToProps功能。

index.tsx

import React from 'react';
import { connect } from 'react-redux';
import { open as openModal } from './actions';
import ContentAddToAlbumModal from './components/ContentAddToAlbumModal';
import AddSection from './components/AddSection';
const MODAL_CONTENT_ADD_TO_ALBUM = 'MODAL_CONTENT_ADD_TO_ALBUM';

export function AddToAlbumButton(props) {
  return (
    <>
      <AddSection onClick={props.openUploadModal} />
      <ContentAddToAlbumModal />
    </>
  );
}

function mapDispatchToProps(dispatch, props) {
  return {
    openUploadModal() {
      return dispatch(openModal(MODAL_CONTENT_ADD_TO_ALBUM, props.content.get('id')));
    },
  };
}

export default connect(null, mapDispatchToProps)(AddToAlbumButton);

components/ContentAddToAlbumModal.tsx

import React from 'react';

export default function ContentAddToAlbumModal() {
  return <div>real ContentAddToAlbumModal</div>;
}

components/AddSection.tsx

import React from 'react';

export default function AddSection({ onClick }) {
  return <div onClick={onClick}>real AddSection</div>;
}

actions.ts

export function open(type, id) {
  return { type, payload: { id } };
}

index.test.tsx

import { render, fireEvent, screen } from '@testing-library/react';
import React from 'react';
import { Provider } from 'react-redux';
import createMockStore from 'redux-mock-store';
import AddToAlbumButton from './';

const mockStore = createMockStore();

jest.mock('./components/ContentAddToAlbumModal', () => {
  return function ContentAddToAlbumModal() {
    return <div>ContentAddToAlbumModal</div>;
  };
});

jest.mock('./components/AddSection', () => {
  return function AddSection({ onClick }) {
    return <div onClick={onClick}>AddSection</div>;
  };
});

describe('AddToAlbumButton', () => {
  test('should pass', () => {
    const store = mockStore({});
    const content = {
      get(key) {
        return '123';
      },
    };
    render(
      <Provider store={store}>
        <AddToAlbumButton content={content} />
      </Provider>
    );
    fireEvent.click(screen.getByText(/AddSection/));
    expect(store.getActions()).toEqual([{ type: 'MODAL_CONTENT_ADD_TO_ALBUM', payload: { id: '123' } }]);
  });
});

测试结果:

 PASS  examples/69525117/index.test.tsx (8.636 s)
  AddToAlbumButton
    ✓ should pass (35 ms)

------------|---------|----------|---------|---------|-------------------
File        | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
------------|---------|----------|---------|---------|-------------------
All files   |     100 |      100 |     100 |     100 |                   
 actions.ts |     100 |      100 |     100 |     100 |                   
 index.tsx  |     100 |      100 |     100 |     100 |                   
------------|---------|----------|---------|---------|-------------------
Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        9.788 s, estimated 10 s
于 2021-10-12T03:07:50.747 回答