beforeEach 不开玩笑地执行

Xee*_*een 4 reactjs jestjs redux enzyme

describe('DropDown', () => {
  let store: any;
  let wrapper: any;

  beforeEach(() => {
    store = mockStore({
      dropDown: {
        ...
      },
    });
    wrapper = mount(
      <Provider store={store}>
        <DropDown />
      </Provider>
    );
  });

  it('Search should update the list', () => {
    const searchField = wrapper.find('.textInput');
    searchField.simulate('change', {
      target: {
        value: 'First customer',
      },
    });
    expect(wrapper.find('.customersList .list li').length).toBe(1);
  });
})
Run Code Online (Sandbox Code Playgroud)

我在块中得到了一个Cannot read property 'find' of undefinedonwrapper元素it。为什么?如果我更新它let wrapper: any = null,那么它就会切换到cannot read property on null这样该beforeEach块就不会被调用。有人知道为什么吗?

编辑:我喜欢@colinux的答案,所以我接受了它,但我的实际原因是该store对象dropDown已被重命名,并且由于某种原因它破坏了与它无关的东西。

col*_*nux 5

由于 Jest 执行测试的方式(由于模拟和并行性等),在beforeEach和 朋友中分配外部变量是不安全的。

相反,对于这种模式,最好定义一个通用方法并在每个测试中手动调用它。

describe('DropDown', () => {
  function prepare() {
    const store = mockStore({
      dropDown: {},
    });

    const wrapper = mount(
      <Provider store={store}>
        <DropDown />
      </Provider>,
    );

    return { store, wrapper };
  }

  it('Search should update the list', () => {
    const { wrapper } = prepare();

    const searchField = wrapper.find('.textInput');
    searchField.simulate('change', {
      target: {
        value: 'First customer',
      },
    });

    expect(wrapper.find('.customersList .list li').length).toBe(1);
  });
});
Run Code Online (Sandbox Code Playgroud)

prepare方法返回可在测试中使用的变量。每次测试都能得到它需要的东西。如果您需要创建一个稍微不同的商店进行测试,您还可以使用可选参数改进该方法。

编辑:此模式在此处的测试库中详细描述https://kentcdodds.com/blog/avoid-nesting-when-youre-testing