spyOn not working while Jest 24.1 is installed - reactjs

In my package.json I have jest 24.1.0 yet my test tell me
"TypeError: _jest.default.spyOn is not a function"
The Jest docs say spyOn is a method I can use but somehow it is not available to me. What am I doing wrong?
https://jestjs.io/docs/en/jest-object#jestspyonobject-methodname
here is my test...
import React from 'react';
import jest from 'jest';
import Enzyme, { shallow } from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';
Enzyme.configure({adapter: new Adapter()});
import NavLink from '../Tabs/NavLink';
describe('NavLink', () => {
it('handles onClick prop', () => {
const onClick = jest.fn();
const e = jest.spyOn('e', ['preventDefault']);
const wrapper = shallow(
<NavLink onClick={onClick} />
);
wrapper.find('a').simulate('click', e);
expect(onClick).toHaveBeenCalled();
expect(e.preventDefault).not.toHaveBeenCalled();
});
}

Just remove this line:
import jest from 'jest';
Jest finds and runs your tests, so jest already exists in the scope of your test by the time it is running. There is no need to import it and doing so is causing the error you are seeing.

Related

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

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

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

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

React jest test with enzyme error

Trying to test my react-native app with jest and enzyme as follows.
import 'react-native';
import React from 'react';
import renderer from 'react-test-renderer';
import { shallow } from 'enzyme';
import { SignUp } from '../../src/pages';
describe('Testing SignUp component', () => {
it('renders as expected', () => {
const wrapper = shallow(
<SignUp />
);
expect(wrapper).toMatchSnapshot();
});
});
on running npm test I get error Cannot find module 'enzyme/build/ShallowTraversal' from 'shallow.js'
test suite failed to run.
Please note that test done minus enzyme runs properly
test('SignUp Page renders correctly', () => {
const tree = renderer.create(<SignUp />).toJSON();
expect(tree).toMatchSnapshot();
});
What could be wrong?
Just solved the problem by first installing enzyme-to-json; npm install --save-dev enzyme-to-json
imported toJson inside my test_file.js
import 'react-native';
import React from 'react';
import renderer from 'react-test-renderer';
import { shallow } from 'enzyme';
import toJson from 'enzyme-to-json'; //added this line
changed the test to this
describe('Testing SignUp component', () => {
it('renders as expected', () => {
const wrapper = shallow(
<SignUp />
);
expect(toJson(wrapper)).toMatchSnapshot(); //edited this line
});
});
changed snapShotSerializers in package.json
"preset": "react-native",
"collectCoverage": true,
"collectCoverageFrom": [
"**/src/**.{js,jsx}"
],
"snapshotSerializers": ["enzyme-to-json/serializer"] //added this line
Now my tests are running correctly.

Typescript, Jest and i18next: Can't see text in React component

I am testing a React component that uses i18next for internationalization.
The component:
import * as React from "react";
import { t } from "i18next";
export function Hello(_props) {
return <div className="widget-header">
{t("Hello, world!")}
</div>;
}
The test:
import * as React from "react";
import { render } from "enzyme";
import { Hello } from "./hello";
describe("<Hello />", () => {
it("says hi", () => {
let hi = render(<Hello />);
// FAILS!
// Expected "" to contain "Hello"
expect(hi.text()).toContain("Hello");
});
})
My suspicion is that Jest is stubbing i18next.t() to return undefined rather than "Hello, world!", but I am unsure of that.
I have tried to unmock("i18next") without any luck.
How do I write tests for i18next components in Jest?
UPDATE: I was using Typescript as my compiler. It appears that there is a hoisting issue with the loader I use for Typescript (ES6 hoists imports, jest.unmock is not- Babel users have a plugin to handle this).
Not sure why its not working but you can just mock put i18next like this:
jest.mock('i18next', () => ({
t: (i) => i
}))

Resources