【问题标题】:Invalid Chai property: toMatchSnapshot -- React.js Jest testing无效的 Chai 属性:toMatchSnapshot -- React.js Jest 测试
【发布时间】:2018-05-30 07:05:12
【问题描述】:

当我尝试使用 Jest + Enzyme 的快照测试时,我收到一个错误:Invalid Chai property: toMatchSnapshot。我已将我的 React 版本更新到 16.2,并使用带有 Enzyme 3 的 enzyme-to-json 库。

代码如下:

import React from 'react';
import ReactDOM from 'react-dom';
import ConnectedApp, { App } from './App';
import { ConnectedRouter } from 'react-router-redux';
import { Provider } from 'react-redux';
import { expect } from 'chai';
import { mount, shallow } from 'enzyme';
import createHistory from 'history/createMemoryHistory'
import configureMockStore from 'redux-mock-store';
import thunk from 'redux-thunk';
import toJson from 'enzyme-to-json';

describe('App tests', () => {
  const middlewares = [thunk];
  const mockStore = configureMockStore(middlewares);
  let store, container, history, wrapper;

  const initialState = {
    output: true
  }

  beforeEach(() => {
    store = mockStore(initialState);
    history = createHistory();
    wrapper = mount(
      <Provider store={store}>
        <ConnectedRouter history={history}>
          <ConnectedApp />
        </ConnectedRouter>
      </Provider>
    )  
  });

  it('+++capturing Snapshot of App', () => {
    expect(toJson(wrapper)).toMatchSnapshot();
  });
})

我也尝试过使用 Jest 的渲染,如下所示:

import renderer from 'react-test-renderer';

it('renders correctly', () => {
  var component = <Provider store={store}>
                    <ConnectedRouter history={history}>
                      <ConnectedApp />
                    </ConnectedRouter>
                   </Provider>
  const tree = renderer
    .create(component)
    .toJSON();
  expect(tree).toMatchSnapshot();
});

但我仍然收到Invalid Chai property: toMatchSnapshot 错误。有谁知道怎么回事?

【问题讨论】:

    标签: reactjs testing chai enzyme jestjs


    【解决方案1】:

    这不是您使用的渲染器的问题。问题是您使用的是 chai 期望而不是 jest 附带的期望库。 chai API 没有toMatchSnapshot 方法。要修复它,您可以执行以下操作:

    1. 停止使用 chai 并专门使用开玩笑的期望。这可能只是删除第 6 行的问题:import { expect } from 'chai'

    但是,如果您需要继续使用 chai(即您已经编写了很多 chai 测试并且您不想一次进行大修),您可以做两件事:

    1. 在测试设置文件中为 chai 或 jest expect 函数命名,例如global.chaiExpect = chai.expect
    2. Monkey-patch 全局 expect 函数,以便您可以同时使用 chai 和 jest API,就像这篇博文中一样:https://medium.com/@RubenOostinga/combining-chai-and-jest-matchers-d12d1ffd0303

      相关位是这样的:

    // Make sure chai and jasmine ".not" play nice together
    const originalNot = Object.getOwnPropertyDescriptor(chai.Assertion.prototype, 'not').get;
    Object.defineProperty(chai.Assertion.prototype, 'not', {
      get() {
        Object.assign(this, this.assignedNot);
        return originalNot.apply(this);
      },
      set(newNot) {
        this.assignedNot = newNot;
        return newNot;
      },
    });
    
    // Combine both jest and chai matchers on expect
    const originalExpect = global.expect;
    
    global.expect = (actual) => {
      const originalMatchers = originalExpect(actual);
      const chaiMatchers = chai.expect(actual);
      const combinedMatchers = Object.assign(chaiMatchers, originalMatchers);
      return combinedMatchers;
    }; 
    

    【讨论】:

    • 这就是我认为正在发生的事情。但是我只是使用了常规的 create-react-app 配置——它应该与 Jest 一起完全配置,对吗?不确定 Chai 在哪里/为什么会出现在照片中。你知道如何禁用 chai 吗?
    • 在第 6 行,您正在从 chai 导入 expect 函数。您可以简单地删除它,它将使用全局 expect
    • 感谢@Sanborn 为您澄清。但我只有一个非常天真的怀疑,即您给出的解决方法,即 global.chaiExpect = chai.expect。我需要在我的 .spec.js 文件中更改这个,因为我无法在我的项目中找到测试设置文件。请帮助我。
    • @AlokRanjan 您可以在 package.jsonjest.config.js 文件中配置 jest。您可以配置很多东西,但对于这个问题,您可以在配置中提供一个setupFilesAfterEnv 数组,其中包括您要运行的安装文件。使用上面的 monkeypatch 在项目的根目录创建一个 testConfig.js 文件,然后将其包含在您的 jest.config.js 文件中,如下所示 javascript modules.exports = { setupFilesAfterEnv: [ '&lt;rootDir&gt;/testConfig.js', ], } 参见:jestjs.io/docs/en/configuration#setupfilesafterenv-array
    【解决方案2】:

    它很简单。只需将您的测试脚本 (something.spec.js) 写入另一个文件,而无需导入 'chai' 。它会像魅力一样工作。不需要乱七八糟的东西。保持简单!

    【讨论】:

      【解决方案3】:

      这与这篇文章部分相关,其他作者给出的根本原因非常准确且信息量很大。

      当我尝试使用 expect(container).toHaveLength(1); 时,我也遇到了与本文中讨论的问题相同的问题

      我通过改变以 Jest 方式编写断言的方式解决了这个问题,例如, expect(container).to.have.length(1);

      因此,如果我们使用 Jest,基本上我们需要找到将断言更改为以 Jest 方式编写的方法。

      希望它可以帮助某人。

      【讨论】:

        猜你喜欢
        • 2019-01-30
        • 2019-07-01
        • 2022-08-19
        • 2019-08-28
        • 2018-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多