无效的 Chai 属性:toMatchSnapshot -- React.js Jest 测试

Posted

技术标签:

【中文标题】无效的 Chai 属性:toMatchSnapshot -- React.js Jest 测试【英文标题】:Invalid Chai property: toMatchSnapshot -- React.js Jest testing 【发布时间】: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 错误。有谁知道怎么回事?

【问题讨论】:

【参考方案1】:

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

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

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

    在测试设置文件中为 chai 或 jest expect 函数命名,例如global.chaiExpect = chai.expect

    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 方式编写的方法。

希望它可以帮助某人。

【讨论】:

以上是关于无效的 Chai 属性:toMatchSnapshot -- React.js Jest 测试的主要内容,如果未能解决你的问题,请参考以下文章

使用 Mocha 和 Chai-as-Promised 测试被拒绝的 Promise 的特定属性

如何检查两个对象是不是具有相同的一组属性名称?

如何将 chai-things 和 chai-like 结合起来?

如何更换Chai期望的Jext预期类型?

节点/no-unpublished-import:“chai”未发布

比较 chai 中的数组