How can I export the component class and that class method? - javascript

For jest test file I want to import component and that method.
For example I have this component :
import React from 'react'
class Dashboard extends React.Component {
constructor(props) {
super(props)
}
sum(one, two) {
return one + two
}
render() {
return(
<div>
<h1>{this.sum(12, 14)}</h1>
</div>
)
}
}
export default Dashboard
So, in the test file I like to test component with render and sum function with toEqual :
import React from 'react';
import ReactDOM from 'react-dom';
import Dashboard from '../Dashboard';
it('check component', () => {
const div = document.createElement('div');
ReactDOM.render(<Dashboard />, div);
});
it('check sum function', () => {
expect(sum(12, 12)).toEqual(24);
});
But the second test and sum has failed, because the test function could not find sum function ...
How can I export component and that contain method ?
Thanks

If you want test a function, that doesn't depend on a component you can use static modifier:
import React from 'react'
class Dashboard extends React.Component {
constructor(props) {
super(props)
}
static sum(one, two) {
return one + two
}
render() {
return(
<div>
<h1>{Dashboard.sum(12, 14)}</h1>
</div>
)
}
}
export default Dashboard
it('check component', () => {
const div = document.createElement('div');
ReactDOM.render(<Dashboard />, div);
});
it('check sum function', () => {
expect(Dashboard.sum(12, 12)).toEqual(24);
});
In most cases it isn't necessary to test react-component methods separately.
Another way to solve you problem is move sum to separate module. Then you can add unit tests to this module.

Related

Jest throwing render error when loading functional child component

I am getting Error: Uncaught [Error: Child(...): Nothing was returned from render when running a test file for the Parent component.
These are the relevant files
/components/Page/Children/Child.js
import React from "react"
export default function Child() {
return <div>abc</div>
}
/components/Page/Children/index.js
export { default } from "./Child"
/components/Page/Parent.js
import React from "react"
import Child from "./Children"
export default class Parent extends React.Component {
constructor(props) {
super(props)
}
render() {
return <Child />
}
}
/components/Page/_tests_/Parent.spec.js
import Parent from "../Parent"
jest.mock("../Children")
describe("<Parent/>", () => {
let wrapper
let props = ...
describe("render", () => {
it("renders", () => {
wrapper = mount(<Parent props={props} />)
expect(wrapper).toMatchSnapshot()
})
})
changing the Child.js file to a react class component (as updated below) resolves the issue but I do not understand why that would be.
/components/Page/Children/Child.js
import React from "react"
export default class Child extends React.Component {
render() {
return <div>abc</div>
}
}
The reason why this error happened is you are mocking the ./Children module and you didn't provide a mocked Child component. So, if you want to mock the Child component, you need to provide a return statement.
E.g.
Parent.spec.js:
import React from 'react';
import Parent from './Parent';
jest.mock('./Children', () => {
return jest.fn(() => <div>mocked child</div>);
});
describe('<Parent/>', () => {
let wrapper;
let props = {};
describe('render', () => {
it('renders', () => {
wrapper = mount(<Parent props={props} />);
expect(wrapper).toMatchSnapshot();
});
});
});
unit test result:
PASS src/stackoverflow/63607465/Page/Parent.spec.js
<Parent/>
render
✓ renders (37ms)
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 1 passed, 1 total
Time: 2.792s, estimated 3s
snapshot:
// Jest Snapshot v1,
exports[`<Parent/> render renders 1`] = `
<Parent
props={Object {}}
>
<mockConstructor>
<div>
mocked child
</div>
</mockConstructor>
</Parent>
`;

Jest manual mock not getting executed for Higher Order Function

I am new to Jest, I am trying to mock my context HOC function to test my component
Here is my folder structure
Folder Structure
Basically I am trying to mock the homeContext.js file which is being used by my HomeScreen component. As per the docs I have created a __mocks__ folder under the contexts folder and created a homeContext.js file
Here are the contents of the files:
/contexts/__mocks__/homeContext.js
const mock = jest.fn().mockImplementation(() => {
console.log('Mocking');
return {
withHomeContext: jest.fn(() => {}),
};
});
module.exports = mock;
contexts/homeContext.js
export const withHomeContext = ChildComponent => props => {
console.log('Not Hitting');
return (
<HomeContext.Consumer>
{context => <ChildComponent {...props} homeContext={context} />}
</HomeContext.Consumer>
);
};
Here is how I am trying to use it in my scenes/home/index.test.js
jest.mock('../../contexts/homeContext');
import React from 'react';
import {mount} from 'enzyme';
import HomeScreen from './index';
describe('<HomeScreen /> renders', () => {
let wrapper;
beforeEach(() => {
wrapper = mount(<HomeScreen />);
expect(wrapper).toBeDefined();
});
})
This is how the component which I am testing uses it
import * as React from 'react';
//Context
import {withHomeContext} from '../../contexts/homeContext';
class HomeScreen extends React.Component {
constructor(props) {
super(props);
this.state = {
relatedItems: [],
};
}
render() {
//Some render logic
}
}
export default withHomeContext(HomeScreen);
Please help me why my __mocks__/homeContext.js never gets hit, it is hitting the actual file, which console logs ('Not Hitting')

React infinite loop caused by component

I'm currently in the process of learning react and have come across a problem has had me stuck for most of the day. I have two simple components. Once called IncidentsBoard which holds other components called Incidents.
The idea is that (using dummy data) the IncidentBoard will show incidents of car crashes on it. My code:
IncidentBoard:
import React from 'react';
import Incident from './Incidents';
import testData from './testdata';
class IncidentBoard extends React.Component {
constructor(props) {
super(props);
this.state = {
data: testData.features,
filtered: []
}
}
componentWillMount() {
var filtered = this.state.data.filter( (incident, i) => {
return incident.properties.event_type === 'Crash';
})
console.log(filtered);
this.setState({filtered})
}
render() {
return <div>
{this.state.filtered.map((incident, i) => {
return <Incident id={i} description="swagg" />
})}
</div>
}
}
export default IncidentBoard;
Incident (which is currently mostly empty):
import React from 'react';
class Incident extends React.Component {
render() {
return <div><h1>test</h1></div>
}
}
export default Incident;
When running this, it causes an infinite loop where componentWillMount() is run without end. I have also noticed that if I replace the Incident component in the render function in IncidentBoard that the error no longer happens.
EDIT: More code
index.js
import React from 'react';
import ReactDOM from 'react-dom';
import IncidentBoard from './Incidents';
ReactDOM.render(
<IncidentBoard />, document.getElementById('react-container')
)
testData is a just a big JSON object.

Test whether React component has rendered

I have a React component that I am trying to test using Enzyme/Jest. I am trying to figure out what the most appropriate test would be to ensure the component has rendered.
My component has a prop shouldRender that, if false, will cause the component to not render. My component looks like this:
import React from 'react';
const propTypes = {
shouldRender: React.PropTypes.bool,
};
class MyComponent extends React.Component {
constructor(props) {
super(props);
this.state = {
foo: 'bar',
};
}
render() {
if (!this.props.shouldRender) {
return null;
}
return (
<div>
<span>My component</span>
</div>
);
}
}
MyComponent.propTypes = propTypes;
export default MyComponent;
I have a test that looks like this:
import React from 'react';
import { shallow } from 'enzyme';
import MyComponent from '../MyComponent';
describe('MyComponent', () => {
it('Should render if we want it to', () => {
const component = shallow(<MyComponent shouldRender />);
expect(component).toBeDefined(); // Passes
});
it('Should not render if we do not want it to', () => {
const component = shallow(<MyComponent />);
expect(component).not.toBeDefined(); // Does not pass, as component isn't undefined.
});
});
I'd like the second test to fail, as the component isn't rendering. Is there a better way to go about testing whether or not a component has rendered?
Happy to provide any more information if it is needed.
Thanks!
So I've had a chat to some people and decided that maybe I am going about this the wrong way.
It's probably a better idea to determine whether or not this gets rendered by the parent component, otherwise any time I want to use MyComponent, I am going to have to pass this shouldRender prop into it.
MyComponent now looks like this:
import React from 'react';
class MyComponent extends React.Component {
constructor(props) {
super(props);
this.state = {
foo: 'bar',
};
}
render() {
return (
<div>
<span>My component</span>
</div>
);
}
}
MyComponent.propTypes = propTypes;
export default MyComponent;
and MyParentComponent that uses MyComponent looks like this:
import React from 'react';
const propTypes = {
myComponent: React.PropTypes.bool,
};
class MyParentComponent extends React.Component {
constructor(props) {
super(props);
this.state = {
boz: 'baz',
};
}
render() {
return (
<div>
{ this.props.myComponent &&
<MyComponent />
}
</div>
);
}
}
export default MyComponent;
Not only does allow MyComponent to be more reusable, it removes the need for the test I wanted to write altogether. Thank you to everyone that looked at this.
I think Jest's snapshot testing is what you need. With snapshot testing when a test fails you can check to see if it's intended or unintended change. Check out their example here

React Jest Test Failing - type.toUpperCase is not a function

I'm trying to write tests using Jest for React. However, I'm getting the following error:
TypeError: type.toUpperCase is not a function
React (images.js):
import React, { Component } from 'react';
export class Images extends Component {
render() {
return (
<div class="images">
</div>
);
}
}
Test (Jest):
jest.autoMockOff();
import React from 'react';
import TestUtils from 'react-addons-test-utils';
const ImagesComponent = require('../src/Components/images');
describe('ImagesComponent', () => {
it('Render instance of div class=images in DOM', () => {
const shallowRenderer = TestUtils.createRenderer();
shallowRenderer.render(<ImagesComponent className="images" />);
imagesDivComponent = shallowRenderer.getRenderOutput();
expect(imagesDivComponent.props.className).toEqual('images');
});
});
Redefine your React component from:
export class Images extends Component {...}
to:
var Images = React.createClass ({...)};
module.exports = Images;

Categories

Resources