Testing React/Jest component with Window.onload - javascript

I'm testing a functional component that uses Window.onload to stay on a certain page. Example of the code
function SignUpForm(props) {
const history = useHistory();
const {setOnPage } = props;
window.onload = setOnPage("/registrarse")
My test is:
import React from 'react'
import Enzyme from "enzyme";
import { screen, render } from '#testing-library/react'
import SignInScreen from './SignInScreen'
import Adapter from "enzyme-adapter-react-16"
const { shallow } = Enzyme;
Enzyme.configure({ adapter: new Adapter() })
describe('Test for login in form', () => {
test("renders correctly", () => {
shallow(<SignInScreen/>);
});
});
The error is in the line of Window.onload, I have not been able to find any solution that can help me.
setOnPage is not a function

Related

Simple React button test fails

Im using jest to test a simple button in React and it keeps failing. My latest iteration complains about render. I'm new to testing and I've been at it for a while and cannot figure this out. What am I missing here?
Here's my App.js
function clickMe() {
alert("Hello")
}
function App() {
return (
<div className="App">
<button id="btn" onClick={clickMe}>Click Me!!</button>
</div>
)
}
export default App;
Here's my App.test.js
import React from 'react'
import {render} from 'react-dom'
import App from './App'
test("Click", () => {
const {container} = render(<App />)
const button = getByTestId(container, 'btn')
fireEvent.click(button)
})
You can simulate some events with the enzyme library
For this first install this by npm, then import that
import {shallow} from 'enzyme';
After using this structure to simulate a click on a bottom
Create a wrapper
let wrapper = shallow(<App />);
beforeEach( ()=>{
wrapper = shallow(<CounterApp />);
});
This creates a simulation of render components and gives you the capacity to simulate events, this method is working in my project counterApp
test('Click', ()=>{
wrapper.find('button').at(0).simulate('click');
expect(//The action of your botton).toBe(//the result expected);
});
Not exactly the same but something like this also worked
import { shallow } from 'enzyme'
import { configure } from 'enzyme'
import Adapter from 'enzyme-adapter-react-16'
import App from './App'
configure({ adapter: new Adapter() })
it('renders the link inside the output area', () => {
const output = shallow(<App />)
expect(output.find('div').find('button').length).toEqual(1)
})

React testing mock variable in functional component

Please help.
I cannot run test because in my util langProvider is package that drops tests.
I have to mock langProvider function or strings variable.
How I can do that?
import React, { ReactElement, useState } from 'react';
import langProvider from 'utils/langProvider';
import { HeaderStyled, DropDownStyled } from './styled';
import './style.scss';
function Header(props: any): ReactElement {
const [state, setState] = useState({
isDropDownOpened: false,
isDrawerOpened: false,
});
const strings = langProvider(props.language, 'components.header');
return (
<HeaderStyled className="header">
...
</HeaderStyled>
);
}
const mapStateToProps = (state: any) => ({
language: state.language,
});
export default connect(mapStateToProps)(Header);
My test file
import { configure, shallow } from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';
import React from 'react';
import Header from './index';
configure({ adapter: new Adapter() });
describe('<Header />', () => {
const wrapper = shallow(<Header />);
it('My test', () => {
expect('').toEqual('Header');
});
});
not sure, but you can try to insert in your test file before describe function, something like that:
jest.mock("utils/langProvider", () => ({langProvider: ()=> []}));

Shallow Rendering with enzyme: actual and expected output does not match

I am just writing code on a personal project for learning.
I have a class defined as below:
import React from 'react';
export default class Counter{
counterValue = 0;
update(newValue){
this.counterValue = newValue;
}
getValue(){
return this.counterValue;
}
displayValue(){
return <div>{this.getValue()}</div>
}
}
I am trying to create a test on the displayValue() function. Code is below:
import React from "react";
import Counter from "./Counter";
import Adapter from "enzyme-adapter-react-16";
import { shallow, mount, render, configure } from "enzyme";
configure({ adapter: new Adapter() });
var c1 = new Counter();
c1.update(188);
describe("check displayValue() method", () => {
it("renders a div", () => {
const wrapper = shallow(c1.displayValue());
expect(wrapper.contains(<div>188</div>)).toBe(true);
});
});
I used the command npm test and a 'react-scripts test' was executed.
The test fails. It tells me that
expect(received).toBe(expected) // Object.is equality
Expected: true
Received: false
and the error is due to this line:
expect(wrapper.contains(<div>188</div>)).toBe(true);
I have trouble understanding this and would appreciate advice. Thank you!
you need to add {} to the number like this:
import React from "react";
import Counter from "./Counter";
import Adapter from "enzyme-adapter-react-16";
import { shallow, mount, render, configure } from "enzyme";
configure({ adapter: new Adapter() });
var c1 = new Counter();
c1.update(188);
describe("check displayValue() method", () => {
it("renders a div", () => {
const wrapper = shallow(c1.displayValue());
expect(wrapper.contains(<div>{188}</div>)).toBe(true);
});
});
for more detail check here

Testing for a 'null' component return value in React with Jest and Enzyme

As the title states I'm trying to test for a null return value on a react component.
I have tried the solution here, but code coverage is saying we haven't properly tested for line 7: return null. What am I missing here?
Component:
import React from 'react';
import { func, bool } from 'prop-types';
import CloudyAlert from '../../assets/alert_cloud.svg';
const Alert = props => {
if (!props.show) {
return null;
}
return (
<div onClick={props.onDismiss} className="alert">
<img src={CloudyAlert} alt="alert to let you know time is up" />
<button>Ok</button>
</div>
);
};
Alert.propTypes = {
onDismiss: func.isRequired,
show: bool
};
export default Alert;
Test:
import React from 'react';
import Enzyme from 'enzyme';
import Alert from '../Alert';
import { mount, shallow } from 'enzyme';
import toJson from 'enzyme-to-json';
import Adapter from 'enzyme-adapter-react-16';
Enzyme.configure({ adapter: new Adapter() });
describe('Alert', () => {
it('renders when show is true', () => {
let wrapper = mount(<Alert onDismiss={jest.fn()} show />);
it('renders correctly', () => {
expect(toJson(wrapper)).toMatchSnapshot();
});
it('shows alert when start is clicked and time is zero', () => {
expect(wrapper.find('Alert').props().show).toBe(true);
});
it('does not show alert when show is false', () => {
wrapper = shallow(<Alert show={false} />);
expect(wrapper.type()).toEqual(null);
});
});
});
Solved: the relevant test was nested in another 'it' block

Why is this Jest/Enzyme setState test failing for my React app?

Expected:
Test runs and state is updated in the Login component, when then enables the Notification component (error message) to be found
Results:
Test fails, expected 1, received 0
Originally before I added redux and the store, thus needing to use the store and provider logic in my test, this Jest/Enzyme tests were passing.
The Login.test (updated current version)
import React from 'react'
import { Provider } from "react-redux"
import ReactTestUtils from 'react-dom/test-utils'
import { createCommonStore } from "../../store";
import { mount, shallow } from 'enzyme'
import toJson from 'enzyme-to-json'
import { missingLogin } from '../../consts/errors'
// import Login from './Login'
import { LoginContainer } from './Login';
import Notification from '../common/Notification'
const store = createCommonStore();
const user = {
id: 1,
role: 'Admin',
username: 'leongaban'
};
const loginComponent = mount(
<Provider store={store}>
<LoginContainer/>
</Provider>
);
const fakeEvent = { preventDefault: () => '' };
describe('<Login /> component', () => {
it('should render', () => {
const tree = toJson(loginComponent);
expect(tree).toMatchSnapshot();
});
it('should render the Notification component if state.error is true', () => {
loginComponent.setState({ error: true });
expect(loginComponent.find(Notification).length).toBe(1);
});
});
Login.test (previous passing version, but without the Redux store logic)
import React from 'react'
import ReactTestUtils from 'react-dom/test-utils'
import { mount, shallow } from 'enzyme'
import toJson from 'enzyme-to-json'
import { missingLogin } from '../../consts/errors'
import Login from './Login'
import Notification from '../common/Notification'
const loginComponent = shallow(<Login />);
const fakeEvent = { preventDefault: () => '' };
describe('<Login /> component', () => {
it('should render', () => {
const tree = toJson(loginComponent);
expect(tree).toMatchSnapshot();
});
it('should render the Notification component if state.error is true', () => {
loginComponent.setState({ error: true });
expect(loginComponent.find(Notification).length).toBe(1);
});
});
Your problem is that by mixing the redux store logic into the tests, the loginComponent variable no longer represents an instance of Login, but an instance of Provider wrapping and instance of Login.
Thus when you do this
loginComponent.setState({ error: true })
You're actually calling setState on the Provider instance.
I would recommend testing the LoginComponent you've wrapped with connect to produce LoginContainer separately from the store state. The Redux GitHub repo has a great article on testing connected components, which gives a general outline on how to do this.
To summarize what you need to do
Export both LoginComponent and LoginContainer separately
Test LoginComponent individually from the container, essentially doing what your previous working tests before mixing in redux store state did.
Write separate tests for LoginContainer where you test the mapStateToProps, mapDispatchToProps and mergeProps functionality.
Hope this helps!

Categories