this is my collegeName.test.js
import React from 'react';
import Enzyme, { shallow, mount } from 'enzyme';
import PersonalProfile from '../../../components/Profile/Tabs/Personal';
import Adapter from "enzyme-adapter-react-16";
import { Provider } from "react-redux";
import configureMockStore from "redux-mock-store";
import configureStore from "../../../redux/configureStore";
import { fetchData, mutateData } from "../../../utils/graphqlUtility";
Enzyme.configure({ adapter: new Adapter() })
const store = configureStore();
//const store = mockStore({});
jest.mock('../../../utils/graphqlUtility', () => {
return {
A:"hihihi"
};
});
describe('Personal Profile', () => {
test('renders', () => {
const wrapper = shallow(
<Provider store={store}>
<PersonalProfile />
</Provider>
);
console.log(wrapper)
let tree = wrapper.toJSON();
expect(tree).toMatchSnapshot();
//<div className="row pad"></div>
//expect(wrapper.contains(<label>Bond Expiration Date</label>)).to.equal(true);
//const paragraph = wrapper.find('div')
//console.log("dsdsds",paragraph)
//expect(paragraph).toHaveLength(1)
});
});
In this file, I am shallowing personalprofile component and this personal profile component calls some methods of graphqlutility file so I mocked graphqlutility file. And then while I am consoling the wrapper its showing me like this in console ShallowWrapper {}.I don't know why the console is showing empty?
I have also attached the screenshot of the console. Can anybody help me with this ?
Use the enzyme's debug() function:
console.log(wrapper.debug());
Related
I need to ask about testing React using enzyme and jest. The case is I have a redux connected component wrapped by also connected component.
wrapper.js
import React from "react";
import { connect } from "react-redux";
import { state, actions } from "src/services/common-store/user";
function ApplicationLayout(props) {
return (
<div>
<h1>{props.title}</h1>
<div id="content">
{props.children}
</div>
</div>
);
}
export default connect(state, actions)(ApplicationLayout);
User.js
import React from "react";
import { connect } from "react-redux";
import { state, actions } from "src/services/common-store/user";
import ApplicationLayout from './ApplicationLayout';
function User(props) {
return (
<ApplicationLayout>
<h1>{props.user.name}</h1>
<img src={props.user.img} />
</ApplicationLayout>
);
}
export default connect(state, actions)(User);
in my test file, I already provided Provider with redux mock store.
User.test.js
import React from "react";
import { mount } from "enzyme";
import configureMockStore from "redux-mock-store";
import { Provider } from "react-redux";
import toJson from "enzyme-to-json";
import thunk from "redux-thunk";
import User from "./User.js";
// Mocking Redux store
const mockStore = configureMockStore([thunk]);
const store = mockStore({ title: "Application Layout", user: { name: "andri", img: "https://ava.com/img.jpg" } });
const setup = () => {
return mount(
<Provider store={store}>
<User />
</Provider>
);
};
describe("Test Component", () => {
let wrapper;
beforeEach(() => {
wrapper = setup();
});
describe("Components rendering", () => {
it("Should render without error and match snapshot", () => {
expect(toJson(wrapper)).toMatchSnapshot();
});
});
});
but I keep getting error said that props like title and user are undefined TypeError: Cannot read property 'user' of undefined. what can I do to address this?
When i run my tests, i get the error:
Field must be inside a component decorated with reduxForm()
I am mocking a store, so i would think that would take care of injecting redux on the test but, i'm not really sure.
Inside appointments.js I have a component that has a redux form
import React from 'react';
... other imports
import configureMockStore from 'redux-mock-store';
import { mount } from 'enzyme';
import expect from 'expect';
import { Provider } from 'react-redux';
import { IntlProvider } from 'react-intl';
import LoginSection from '../User/LoginSection';
import AppointmentsContainer from './AppointmentsContainer';
import Appointments from './Appointments';
import AppointmentStatus from .../Layout/AppointmentStatus/AppointmentStatusContainer';
jest.mock('./Appointments');
jest.mock('../User/LoginSection');
jest.mock('../Layout/AppointmentStatus/AppointmentStatusContainer');
const store = configureMockStore()({
form: 'Appointments',
});
const setup = (newProps) => {
const props = {
handleSubmit: jest.fn(),
},
form: 'appointmentsContainer',
locale: 'en',
...newProps,
};
const root = mount(
<Provider store={store}>
<IntlProvider {...props}>
<AppointmentsContainer {...props} />
</IntlProvider>
</Provider>
,
);
const wrapper = root.find(Appointments);
return {
root,
wrapper,
props,
};
};
describe('AppointmentsContainer', () => {
beforeEach(() => {
store.clearActions();
});
Any idea how can i fix this?
I am using Enzyme tests within Create-React-App. In shallow rendering it works fine, but mount rendering throws error:
TypeError: Cannot read property 'favorites' of undefined
Test file looks like this:
import React, { Component } from "react";
import configureMockStore from "redux-mock-store";
import { shallow, mount } from "enzyme";
import { Provider } from "react-redux";
import Favorites from "../Landing/Favorites";
const mockStore = configureMockStore();
const store = mockStore({});
function setup() {
const props = {
favorites: 42
};
const wrapper = mount(
<Provider store={store}>
<Favorites {...props} />
</Provider>
);
return {
props,
wrapper
};
}
describe("Favorites component", () => {
const { wrapper } = setup();
it("should render list of favorites cards", () => {
expect(wrapper.prop("favorites")).toEqual(42);
});
});
Why did it happen?
.prop works different in mount and shallow. You can check the docs.
http://airbnb.io/enzyme/docs/api/ReactWrapper/prop.html
http://airbnb.io/enzyme/docs/api/ShallowWrapper/prop.html
When using mount, you can directly render Favorites component.
mount(<Favorites {...props} />)
have problem with testing redux connected component with enzyme
import React from 'react'
import { shallow, mount, render } from 'enzyme'
import { configure } from 'enzyme';
import Adapter from 'enzyme-adapter-react-15';
import Login from '../../src/routes/login/components/Login'
configure({ adapter: new Adapter() })
describe('<Login />', () => {
test('component has form-group nodes', () => {
const component = shallow(<Login />).dive()
expect(component.find('.form-group')).to.have.length(2)
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
But have error in console - Invariant Violation: Could not find "store" in either the context or props of "Connect(Login)".
how to deal with it??
I faced a similar problem and I managed to solve it by using redux-mock-store for my store mocking and I used mount instead of shallow to reach my connected component with redux like that:
import React, { Component } from 'react';
import { mount } from 'enzyme';
import { expect } from 'chai';
import { Provider } from 'react-redux';
import configureStore from 'redux-mock-store';
import App from '../../src/App';
it('renders without crashing', () => {
const mockStore = configureStore();
const initialState = {
someState: [],
someReducer: {},
};
const store = mockStore(initialState);
const wrapper = mount(
<Provider store={store}>
<App />
</Provider>
);
console.log(wrapper.debug())
expect(wrapper.find('.app-container')).to.have.lengthOf(1);
});
Have a read this best practice from [redux doc][1]
https://github.com/reduxjs/redux/blob/master/docs/recipes/WritingTests.md#connected-components
The issue you have encountered is because you are testing the connected component, what you should be doing is like what the official doc suggested:
export class Login extends Component { /* ... */ }
export default connect(mapStateToProps)(Login )
Instead of unit testing the connected component, you can simply unit test the Login component which you won't need to mock the store etc.
Hope it helps.
I'm trying to wrote test for my react component which using redux and react-intl:
import React from 'react';
import { expect } from 'chai';
import { shallow, mount, render } from 'enzyme';
import Navbar from 'Navbar';
import configureMockStore from 'redux-mock-store'
import thunk from 'redux-thunk'
import { Provider } from 'react-redux';
import messages from '../src/l10n/en.json'
import { IntlProvider } from 'react-intl'
const middlewares = [ thunk ]
const mockStore = configureMockStore(middlewares)
const store = mockStore({})
describe('<Navbar />', () => {
it('calls componentDidMount', () => {
const wrapper = mount(
<Provider store={store}>
<IntlProvider locale={ "en" } messages={ messages }>
<Navbar />
</IntlProvider>
</Provider>
);
expect(Navbar.prototype.componentDidMount.calledOnce).to.equal(true);
});
});
But I got this result:
<Navbar />
1) calls componentDidMount
0 passing (73ms)
1 failing
1) <Navbar /> calls componentDidMount:
AssertionError: expected undefined to equal true
Can some one give me an advise how can I fix it?
The error is because, componentDidMount is not spy'ed in the test. You could use sinon to do fix this issue. For instance,
import React from 'react';
import { expect } from 'chai';
import { shallow, mount, render } from 'enzyme';
import Navbar from 'Navbar';
import configureMockStore from 'redux-mock-store'
import thunk from 'redux-thunk'
import { Provider } from 'react-redux';
import messages from '../src/l10n/en.json'
import { IntlProvider } from 'react-intl'
import { spy } from 'sinon';
const middlewares = [ thunk ]
const mockStore = configureMockStore(middlewares)
const store = mockStore({})
describe('<Navbar />', () => {
it('calls componentDidMount', () => {
spy(Navbar.prototype, 'componentDidMount');
const wrapper = mount(
<Provider store={store}>
<IntlProvider locale={ "en" } messages={ messages }>
<Navbar />
</IntlProvider>
</Provider>
);
expect(Navbar.prototype.componentDidMount.calledOnce).to.equal(true);
});
});
On a side note:- If you want to use react-intl in tests, I would suggest to use helper functions as described here