Reputation: 111
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?
Upvotes: 10
Views: 10154
Reputation: 41
For those transitioning away from chai (which would be hijacking expect()
from jest in the top level setupTests.js
file) the simpler solution is to load jest's expect()
again on top of the current test file like so:
import { expect } from "@jest/globals";
That is, until you can't fully do away with any
global.expect = chai.expect;
somewhere in the code, setupTests.js
for example.
Upvotes: 1
Reputation: 1097
This is partially related to this post & root cause given by other authors are quite accurate and very informative.
I also faced same problem as discussed in this post, when I was trying to use expect(container).toHaveLength(1);
I solved this issue by changing my way to write assertion in Jest way like,
expect(container).to.have.length(1);
So basically we need to find way to change our assertion to write in Jest way, if we are using Jest.
Hope it may help someone.
Upvotes: -2
Reputation: 77
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 !
Upvotes: 0
Reputation: 289
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:
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:
expect
functions in your test setup file e.g. global.chaiExpect = chai.expect
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;
};
Upvotes: 7