Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Invalid Chai property: toMatchSnapshot -- React.js Jest testing

I'm getting an error: Invalid Chai property: toMatchSnapshot when I try to use Jest + Enzyme's snapshot testing. I've updated my React version to 16.2 and I use enzyme-to-json library with Enzyme 3.

Code is below:

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();
  });
})

I've also tried this with Jest's render like so:

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();
});

But I still get the Invalid Chai property: toMatchSnapshot error. Anyone know what's up?

like image 557
Patrick Lu Avatar asked Dec 16 '17 06:12

Patrick Lu


2 Answers

This isn't an issue with the renderer you are using. The problem is that you are using chai expectations instead of the expectation library that ships with jest. The chai API has no toMatchSnapshot method. To fix it you can do the following:

  1. Stop using chai and use the jest expectations exclusively. This may simply be a matter of removing line 6: import { expect } from 'chai'

However, if you need to continue to use chai (i.e. you have a lot of chai tests already written and you don't want to do a major overhaul all at once) you can do two things:

  1. Alias either the the chai or jest expect functions in your test setup file e.g. global.chaiExpect = chai.expect
  2. Monkey-patch the global expect function so that you can use both the chai and the jest API like in this blog post: https://medium.com/@RubenOostinga/combining-chai-and-jest-matchers-d12d1ffd0303

    The relevant bit is this:

// 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;
}; 
like image 123
Sanborn Avatar answered Sep 24 '22 23:09

Sanborn


Its Simple.Just write your test scripts (something.spec.js) in to another file without importing 'chai' . It will work like a charm. No need for messy stuffs.Keep it Simple !

like image 24
shubham pandey Avatar answered Sep 25 '22 23:09

shubham pandey