I am not having this warning probably on the normal functioning of the app but I am having this problem in the unit tests. So I am doing a unit test for a Tabs component and it gives me the following warning:
my jsx file looks like this:
class SimpleTabs extends React.Component {
handleChange = (event, value) => {
const { onChange } = this.props;
onChange(value);
};
render() {
const { classes, selectedChannelIndex } = this.props;
return (
<div className={classes.root}>
<AppBar position="static">
<Tabs
key={selectedChannelIndex}
value={selectedChannelIndex}
onChange={this.handleChange}
classes={{ root: classes.tabsRoot, indicator: classes.tabsIndicator }}
>
{CHANNELS_ARRAY &&
CHANNELS_ARRAY.map((channel, i) => (
<Tab
key={i}
value={i}
label={channel.channel}
classes={{ root: classes.tabRoot, selected: classes.tabSelected }}
/>
))}
</Tabs>
</AppBar>
<TabContainer>{this.props.children}</TabContainer>
</div>
);
}
}
export default withStyles(styles)(SimpleTabs);
and my unit test file looks like this:
import React from 'react';
import Adapter from 'enzyme-adapter-react-16';
import { configure, mount } from 'enzyme';
import { shallowToJson } from 'enzyme-to-json';
import Tabs from '../../../src/components/common/Tabs/Tabs';
configure({ adapter: new Adapter() });
const defaultProps = { selectedChannelIndex: 0, value: 0, selectInput: 0 };
const setup = (props = {}) => {
const setupProps = { ...defaultProps, ...props };
return shallow(<Tabs {...setupProps} />);
};
describe('Tabs', () => {
const wrapper = mount(<Tabs {...defaultProps} />);
it('should be defined', () => {
expect(Tabs).toBeDefined();
});
it('should render correctly', () => {
const tree = mount(<Tabs />);
expect(shallowToJson(tree)).toMatchSnapshot();
});
});
I've seen others asking about this warning as well but many times it's said that to add the value on the tabs element is the solution but is not working for me.
Related
Im a bit new to the react ecosytem. Im having a weird behaviour with passing tests.
Im using CRA, prop-types and react-test-library.
Here is my component:
import React from 'react';
import PropTypes from 'prop-types';
export default function Navbar({
Logo, MenuItems, className,
}) {
return (
<nav aria-label="navigation bar" className={className}>
{Logo}
<div>
{ MenuItems.map((MenuItem) => MenuItem) }
</div>
</nav>
);
}
Navbar.defaultProps = {
className: '',
};
Navbar.propTypes = {
className: PropTypes.string,
Logo: PropTypes.node.isRequired,
MenuItems: PropTypes.arrayOf(PropTypes.node).isRequired,
};
I want to test that prop-types complains when params are not receiving the right type.
import React from 'react';
import { render } from '#testing-library/react';
import Navbar from './Navbar';
describe('<Navbar />', () => {
beforeAll(() => {
jest.spyOn(console, 'error').mockImplementation(() => {});
});
beforeEach(() => {
console.error.mockClear();
});
afterAll(() => {
console.error.mockRestore();
});
it('renders', () => {
render(<Navbar
Logo={<p data-test="logo">My logo</p>}
MenuItems={[
<p key="spanish">Spanish</p>,
<p key="english">english</p>,
]}
/>);
expect(console.error).not.toHaveBeenCalled();
});
it('errors to console when Logo is missing', () => {
render(<Navbar MenuItems={[
<p key="spanish">Spanish</p>,
<p key="english">English</p>,
]}
/>);
expect(console.error).toHaveBeenCalled();
});
it('does not error to console when Logo is missing', () => {
render(<Navbar MenuItems={[
<p key="spanish">Spanish</p>,
<p key="english">English</p>,
]}
/>);
expect(console.error).toHaveBeenCalled();
});
});
My thinking is that Im not resetting properly the mocks, they have some state that it is not clear or something similar.
What am i missing?
PropTypes.checkPropTypes(...) only console.errors a given message once. To reset the error warning cache in tests, call PropTypes.resetWarningCache()
Source
Try invoke resetWarningCache in your beforeEach hooks
import PropTypes from 'prop-types';
beforeEach(() => {
PropTypes.resetWarningCache()
});
I use Two package
slate-react and emoji-mart
I want to when choose an Emoji , it puts on my editor.
import React from "react";
import { render } from "react-dom";
import { Editor } from "slate-react";
import { initialValue } from "./initialValue";
// Define our app...
class MyEditor extends React.Component {
// Set the initial value when the app is first constructed.
state = {
value: initialValue
};
// On change, update the app's React state with the new editor value.
onChange = ({ value }) => {
this.setState({ value });
};
onKeyDown = (event, change) => {
// This used to have stuff in it, but I moved it all to plugins.
};
clickMe=()=>{
this.setState({ value : this.state.value });
};
// Render the editor.
render() {
return (
<div>
<h1 onClick={this.clickMe}>Slate Editor Demo</h1>
<div style={{ border: "1px solid black", padding: "1em" }}>
<Editor
value={this.state.value}
onChange={this.onChange}
onKeyDown={this.onKeyDown}
renderNode={this.renderNode}
spellCheck={false}
/>
</div>
</div>
);
}
}
export default MyEditor;
import React,{useState} from 'react';
import 'emoji-mart/css/emoji-mart.css';
import { Picker } from 'emoji-mart';
function Emoji() {
const [emoji,setEmoji] = useState(null);
const addEmoji = (e) => {
setEmoji(e.native)
};
return <Picker onSelect={addEmoji} />
}
export default Emoji;
Try passing the editor ref to picker. Then in Emoji component in addEmoji method, try editorRef.current.InsertText(e.native). After hours of trying to solve this:
const YourTextEditor = props => {
const editor = createEditor();
const addEmoji = async emoji => {
await setTimeout(() => {
editor.focus();
}, 100);
editor.insertText(emoji.native);
};
return (
<>
<Editor
value={initialValue}
/>
<Emoji addEmoji={addEmoji} />
</>
);
};
const Emoji = props => {
return (<Picker onSelect={e => props.addEmoji(e)} />);
};
When I try to simulate a change event with Enzyme in my Material-UI component, value is not changing.
My component looks like this:
export class EditableList extends Component {
...
onChangeNewEntry = event => {
this.setState({newEntry: event.target.value});
};
render() {
const {classes} = this.props;
return (
<div className={classes.div_main}>
<List>
<Paper className={classes.paper_title} elevation={2} key="NewEntry">
<ListItem>
<InputBase
data-testid='input-base'
className={classes.inputBase}
placeholder="New Entry"
value={this.state.newEntry}
onKeyPress={(event) => {
if (event.key === 'Enter') {
event.preventDefault();
this.onCreateItem();
}
}}
onChange={this.onChangeNewEntry}
multiline
/>
</ListItem>
</Paper>
</List>
</div>
);
}
}
My test looks like this:
import React from 'react';
import {Provider} from "react-redux";
import EditableList from "./EditableList";
import store from "../../../../store";
import {createMount, createShallow} from "#material-ui/core/test-utils";
import {InputBase} from "#material-ui/core";
let mount;
let wrapper;
beforeEach(() => {
mount = createMount();
wrapper = mount(
<Provider store={store}>
<EditableList/>
</Provider>
);
});
afterEach(() => {
mount.cleanUp();
});
const findComponent = ( value) => {
return wrapper.find(`[data-testid='${value}']`).first();
};
it('allow user to write input for new item', () => {
const inputBase = findComponent('input-base');
const value = "New item";
inputBase.simulate('change', {target: {value: value}});
wrapper.update();
console.log(inputBase.prop('value'));
});
In the console, the valueis always an empty string.
I tried also the following without success:
wrapper.find(InputBase).at(0).props().onChange({target: {value: value}});
wrapper.find(InputBase).at(0).props().onChange({target: {name: 'InputBase', value: value}});
This is my functional Component.
const InputText = (props: Props) => {
return (
<div>
<StyledInput type="text" placeholder={props.placeholder} />
<br></br>
</div>
);
};
export default InputText;
and this is my test cases.
enter code here
const wrap = (props: Props) => shallow(<InputText {...props} />);
it("input text change", () => {
// const wrap = (props: Props) => mount(<StyledInput {...props} />);
const wrapper = wrap({ placeholder: "UserName" });
const usernameInput = wrapper.find("input");
usernameInput.simulate("change", { target: { value: "umesh#hcl.com" } });
expect(usernameInput.text()).toEqual("umesh#hcl.com");
});
So this test case failed with error:
Expected "Umesh#hcl.com" and recevide:"";
How can I resolve this?
Check this one
App.test.js
import React from "react";
import { shallow, configure } from "enzyme";
import Input from "./App";
import Adapter from 'enzyme-adapter-react-16';
configure({adapter: new Adapter()});
describe("Input Component", () => {
it("should trigger the onchange", () => {
const wrapper = shallow(<Input />);
wrapper
.find("input")
.simulate("change", { target: { value: "on typing" } });
expect(wrapper.find('input').props().value).toBe('on typing')
});
});
App.js
import React, { useState } from "react";
const InputText = props => {
const [inputText, setInput] = useState("");
const onHandleChange = e => {
setInput(e.target.value);
};
return (
<div>
<input
type="text"
value={inputText}
onChange={onHandleChange}
/>
<br />
</div>
);
};
export default InputText;
It's my first time to write tests. I'm writing tests for a ReactJS app wrote with hooks, and testing using Jest and react-testing-library.
Here's my functional component:
const ItemDetails = ({ item }) => {
const { code } = item;
const { getBarcode } = useStationContext();
return (
<>
<Button
type="primary"
onClick={() => {
getBarcode(code);
}}
style={{ float: 'right' }}
>
Print Barcode
</Button>
<List
bordered
dataSource={formatData(item)}
renderItem={({ title, value }) => (
<List.Item>
<List.Item.Meta
description={
<Wrapper>
<p>{upperCase(title)}</p>
<div>{value}</div>
</Wrapper>
}
/>
</List.Item>
)}
/>
</>
);
};
export default ItemDetails;
and the test file:
import React from 'react';
import { render, cleanup } from 'react-testing-library';
import ItemDetails from '../containers/Items/ItemPage/ItemDetails';
afterEach(cleanup);
describe('formatData()', () => {
it('Return Details about item', async () => {
const { getByText, getByTestId, container, asFragment } = render(
<ItemDetails
item={{
id: '296-c-4f-89-18',
barcode: 'E-6',
}}
/>,
);
global.console = {
log: jest.fn(getByText, getByTestId, container, asFragment),
};
expect(global.console.log).toHaveBeenCalledWith('test');
});
});
When I run the test I got this error:
TypeError: Cannot read property 'getBarcode' of null
I don't know how can I fix this?
The expectations are wrong because console.log isn't called anywhere. Mocking console object like global.console = ... is a bad practice because it persists between tests and can break things that depend on it, including test runner itself.
There's inconsistency with item code key, it was provided as barcode.
Context value is expected to be undefined, unless default value was provided. It should be provided in test.
It likely should be:
const getBarcodeMock = jest.fn();
const { getByText, getByTestId, container, asFragment } = render(
<StationContext.Provider value={{ getBarcode: getBarcodeMock }}>
<ItemDetails
item={{
id: '296-c-4f-89-18',
code: 'E-6',
}}
/>
</StationContext.Provider>
);
// ...simulate button click...
expect(getBarcodeMock).toBeCalledWith('E-6');