Consoling shallow(<component />) results in ShallowWrapper {} - reactjs

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

How to snapshot test connected component that wrapped with connected component?

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?

Field must be inside a component decorated with reduxForm(), Error in test file

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?

Why enzyme tests did not work in React.js?

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} />)

Testing a Redux-connected component using Enzyme

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.

mocha with redux: expected undefined to equal true

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

Resources