如何使用 mobx 可观察状态测试反应组件

How to test react components with mobx observable state

这是我的组件的简化版本:

import React from 'react';
import { observable, action } from 'mobx';
import { observer } from 'mobx-react';
import { fromPromise } from 'mobx-utils';

@observer
export class MyComponent extends React.Component {
  @action componentDidMount() {
    const { store, params } = this.props;
    this.warehouse = store.findById(params.id);
  }

  @observable warehouse = fromPromise(Promise.resolve());

  render() {
    return this.warehouse.case({
      fulfilled: (value) => (
        <div>
          fulfilled
        </div>
      ),
      rejected: (error) => (
        <div>
          rejected
        </div>
      ),
      pending: () => (
        <div>
          pending
        </div>
      )
    });
  }
}

这是我的测试(使用笑话和酶):

import React from 'react';
import { mount } from 'enzyme';
import toJson from 'enzyme-to-json';
import { observable, when } from 'mobx';
import { fromPromise } from 'mobx-utils';

import { MyComponent } from './MyComponent';

describe('<MyComponent>', () => {
  it('should render correctly for state "fulfilled"', (done) => {
    const mockStore = observable({
      findById: jest.fn(() => fromPromise(Promise.resolve({ id: 'id' })))
    });

    const wrapper = mount(<MyComponent store={mockStore} params={{ id: '1' }} />);
    const wh = wrapper.instance().warehouse;

    when(
      () => wh.state === 'fulfilled',
      () => {
        expect(wrapper.text()).toBe('fulfilled');

        done();
      }
    );
  });
});

问题是 when 的处理程序在渲染方法之前的测试 运行 中,所以我无法访问那里的渲染标记。 我的问题是如何在呈现完成状态后 运行 我的 except 代码。 我也不想破解我的组件。这里我用的是我不太喜欢的wrapper.instance().warehouse

一般来说,问题是如何测试其中具有可观察状态的组件?

我最终得到了这个解决方案:

import React from 'react';
import { mount } from 'enzyme';
import toJson from 'enzyme-to-json';
import { observable, when } from 'mobx';
import { fromPromise } from 'mobx-utils';

import { MyComponent } from './MyComponent';

describe('<MyComponent>', () => {
  it('should render correctly for state "fulfilled"', (done) => {
    const mockStore = observable({
      findById: jest.fn(() => fromPromise(Promise.resolve({ id: 'id' })))
    });

    const wrapper = mount(<MyComponent store={mockStore} params={{ id: '1' }} />);
    const wh = wrapper.instance().warehouse;

    when(
      () => wh.state === 'fulfilled',
      () => {
        process.nextTick(() => {
          expect(wrapper.text()).toBe('fulfilled');
          done();
        });
      }
    );
  });
});

mobx-react 项目 issues 中也有一个相关问题。