Unit test React/Redux with Enzyme in 'create-react-app' application - reactjs

I want to do some basic unit test to my app which I created with "create-react-app" package. I believe it already has Jest installed.
I have some basic redux code in my app.
I want to test:
It renders the main component(App.js) without crashing
Clicking to show next item funcion
I have installed Enzyme using "npm install --save-dev enzyme" and "enzyme-adapter-react-15".
Here is my code:
import React from 'react';
import ReactDOM from 'react-dom';
import {App} from './App';
import { shallow, mount, render, configure } from 'enzyme';
import Adapter from 'enzyme-adapter-react-15';
configure({ adapter: new Adapter() });
describe('A test for App component', () => {
let wrapper
beforeEach(()=>{
wrapper = shallow(<App />);
})
it('should render App Component', () => {
expect(wrapper).to.have.length(1)
})
})
I can't get the test to start to work. The error message:
TypeError: Cannot read property 'length' of undefined
and
TypeError: Cannot read property 'have' of undefined
I think there is some basic things I am doing wrong.
Any help is appreciated!!!

You are using Jest's expect function. You need to explicitly declare the import from chai.
it will look something like:
import { expect } from 'chai'
it('should render App Component', () => {
expect(wrapper).to.have.length(1)
})
Also, instead of adding the adapter configuration for each test, you could add a file setupTests.js to /src and it will work for all tests :-)

You probably copied it from the examples on enzyme's website, which uses chai. The jest equivalent for what you're trying to test is:
it('should render App Component', () => {
expect(wrapper).toHaveLength(1)
})

Related

Enzyme / Jest Error testing component render in React (TS)

I've been having an odd issue with Jest/Enzyme testing on my react typescript app. For some reason it gives a syntax error even though this is following the official documentation, as well as input from several articles.
The Code:
import React from 'react';
import NavbarTop from "../components/navbar";
import { shallow } from 'enzyme';
describe('NavbarTop', () => {
it('renders correctly', () => {
const wrapper = shallow(<NavbarTop />);
expect(wrapper).toMatchSnapshot();
// On the first run of this test, Jest will generate a snapshot file automatically.
});
});
The folder structure. I have a named class and then an index with a default export.
The error log.
Do you have JSX configured for Jest? Looks like you don't have support for JSX in Jest, which probably means this is a configuration issue. Have a look at configuring babel to support JSX in Jest.
Make sure you read this tutorial

How do I Import a manually mocked module with mocked data using jest and enzyme?

My test doesn't seem to importing my manual mock under __mocks__/Auth.js.
I have a module that I use, Auth.js in my react application, App.js. I am trying to mock that module using a manual mock by making a mocked file under __mocks__/Auth.js. My __mocks__ is at the same file level as App.js and Auth.js.
I have a repo here: https://github.com/chaselw/reactTesting
Or my test is below:
import React from 'react';
import Enzyme, { shallow, mount } from 'enzyme';
import EnzymeAdapter from 'enzyme-adapter-react-16'
import App from './App';
Enzyme.configure({ adapter: new EnzymeAdapter() });
test('logged in false', () => {
jest.mock('./Auth.js'); //Trying to get `auth.isLoggedIn() === false`
const wrapper = mount(<App />);
console.log(wrapper.debug())
expect(wrapper.exists("[data-test='Logged-In-False']")).toBe(true);
})
Expected result is that the test would return a "Logged-In-False" div from Login module after the if check on auth.isLoggedIn(). However I get the "true" div back.
In the test if I do: console.log(wrapper.auth.isLoggedIn()), it returns .isLoggedIn() is undefined.
I am new to React, jest and enzyme. I have no idea what is wrong, any help would be great! Thanks.
The solution was simple. jest.mock('./Auth.js') needs to be not inside a test, but rather at the top level as the imports.
import React from 'react';
import Enzyme, { shallow, mount } from 'enzyme';
import EnzymeAdapter from 'enzyme-adapter-react-16'
import App from './App';
jest.mock('./Auth');
Enzyme.configure({ adapter: new EnzymeAdapter() });
test('logged in false', () => {
//Trying to get `auth.isLoggedIn() === false`
const wrapper = mount(<App />);
console.log(wrapper.debug())
expect(wrapper.exists("[data-test='Logged-In-False']")).toBe(true);
})

Jest cannot find module from file in the same folder

I'm trying to set up a very basic test with Jest which tests whether App.js renders correctly. I am getting the error
Cannot find module './App' from 'App.test.js'
However, Jest was able to find:
'./App.js'
'./App.test.js'
However, if I try to write import App from "./App.js"; instead of ... from "./App";, I get
Cannot find module './App.js' from 'App.test.js'
How can I make Jest find modules properly?
The project was set up using Create React App, and App.js and App.test.js are located within the same folder (src/components).
App.js
import React, { Component } from "react";
class App extends Component {
render() {
return <div />;
}
}
export default App;
App.test.js
import React from "react";
import { shallow } from "enzyme";
import App from "./App.js";
const app = shallow(<App />);
it("renders correctly", () => {
expect(app).toMatchSnapshot();
});
I think Jest needs to set up itself before rendering components (so don't call <App /> outside of test cases):
it("renders correctly", () => {
const app = shallow(<App />);
expect(app).toMatchSnapshot();
});
However, if the problem is on the import line, assuming you use an up-to-date version and don't pass any CLI options yourself, I would recommend to replace whole content of App.test.js with:
it('', () => console.log(process.env))
and search for the listed environment variables in https://jestjs.io/docs/en/configuration to see if any can affect Jest.

react-lazyload breaks jest snapshots?

I've been working on optimising my react project and today I implemented lazy loading of all my images using react-lazyload (https://github.com/jasonslyvia/react-lazyload).
The package works just fine but as soon as I tried to update my snapshot tests they all failed!
The error I'm getting is:
Uncaught [TypeError: Cannot read property 'position' of undefined]
I tried seeing what I could find on google but nothing came up.
Here is an example of one of my snapshot tests (they're about as basic as can be):
import React from 'react';
import renderer from 'react-test-renderer';
import App from './App';
describe('App', () => {
describe('Component Snapshot', () => {
it('should render correctly', () => {
const componentSnapshot = renderer.create(<App />).toJSON();
expect(componentSnapshot).toMatchSnapshot();
});
});
});
Do I need to mock the lazy load package? If so does anyone have any advice of how I would go about doing that?
Any help is greatly appreciated.
Incase anyone runs into this issue, I solved it by using 'enzyme-to-json' instead of 'react-test-renderer' in conjunction with enzymes own 'render' function.
Here is the updated test so you can see what I mean.
import React from 'react';
import { render } from 'enzyme';
import toJson from 'enzyme-to-json';
import App from './App';
describe('App', () => {
describe('Component Snapshot', () => {
it('should render correctly', () => {
const componentRender = render(<App />);
expect(toJson(componentRender)).toMatchSnapshot();
});
});
});
I don't know the exact reasons why react-test-renderer was bugging out, my gut is telling me that because there isn't a window within node for my lazy-load placeholders to populate there isn't a 'position' to define. I would guess that enzyme has some clever stuff going on behind the scenes to get around that?
If anyone has a more definitive explanation I'd love to hear it, but for now at least the problem is fixed :)

react unit testing - Enzmye shallow

I am trying to setup unit testing in React with Enzyme. When i run the command "npm-test" the test fails.
The console terminal indicates that it failed because of shallow().
I have installed enzyme using this command npm install --save enzyme enzyme-adapter-react-16 react-test-renderer. Do anyone know how to solve this issue?
Below is the component
import React from 'react';
class Login extends Component {
render() {
return <div><input
onChange={(event) => {
this.setState({input: event.target.value})}}
type="text" /></div>;
}
}
export default Login;
This is the unit test i have written for the Component.
import React from 'react';
import { configure, shallow } from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';
import Login from '../../../src/components/authentication/Login';
import Enzyme from 'enzyme';
configure({adapter: new Adapter()});
it("should create an entry in component state with the event value", () => {
// given
const component = shallow(<Login/>);
const form = component.find('input');
// when
form.props().onChange({target: {
name: 'myName',
value: 'myValue'
}});
// then
expect(component.state('input')).toEqual('myValue');
});
Thanks for the help.
Hi perhaps you miss the conventions:
you have to put your test files inside a __tests__ directory and tests file should be named: YourComponent.test.js
Than wrap your test within a test suite:
describe('Your test suite', () => {
test('it should do something', () => {
// the content of your test
});
});

Resources