How can I write react test case for my below code which is part of functional component?
<select id="specialitySelect" onChange={specialityChanged} className="select form-control">
{specialityOptions.map((id) =>
<FormattedMessage id={id}>
{(id) => {
return <option value={id}>{id}</option>
}}
</FormattedMessage>
)}
</select>
I have written below test case, which covers the onChange event but not return option tag
it('should test specialityChanged', () => {
Object.defineProperty(document, 'getElementById', {
value: ()=>{return {value:1}},
});
const renderedModule = shallow(<SearchProviders langPack={{locale:'en-HK'}} analytics=`enter code here`{{analyticsClick:()=>{}}}/>);
const specialityChanged = renderedModule.find('#specialitySelect');
specialityChanged.simulate('change');
expect(specialityChanged).toBeDefined();
});
See also questions close to this topic
-
Updating React state in nested setTimeout callbacks
Can someone please tell me what's wrong with this and why the state of the 'video variable' remains false? So, even after the h2 element has rendered and is visible (i.e. the state of the video variable has been updated to true), when I click and call the hideVideo function, the video state remains false? Many thanks.
export default function App() { const [message, showMessage] = useState(false); const [video, setVideo] = useState(false); let modalTimeout, videoTimeout; useEffect(() => { window.addEventListener("click", hideVideo); setupTimeouts(); return () => { clearTimeout(modalTimeout); clearTimeout(videoTimeout); }; }, []); const setupTimeouts = () => { modalTimeout = setTimeout(() => { showMessage(true); videoTimeout = setTimeout(() => { showMessage(false); setVideo(true); }, 4000); }, 2000); }; const hideVideo = () => { console.log(video); showMessage(false); if (video === true) { setVideo(false); } }; return ( <div className="App"> {message && <h1>Message</h1>} {video && <h2>Video</h2>} </div> ); }
-
React-dnd multiple elements
I can make react-dnd drag easily having a single element to drag over however I have array of 4 fields I'd like to make draggable. In my example code down below it creates four boxes from mapping the array and each box has a className of 'element'. Which should make them all draggable however they won't move.
Here is my drag code:
const ELEMENT = 'element'; const [{ isDragging }, drag, dragPreview] = useDrag(() => ({ type: ELEMENT, collect: (monitor) => ({ isDragging: monitor.isDragging() }) }))
Here is my draggable element:
{FieldDetail.map((e,i) => <div key={i} ref={dragPreview} style={{ opacity: isDragging ? 0.5 : 1}}> <div className='element' ref={drag}></div> </div> )}
Any ideas? Do I need to do something more within the type or className?
-
One connection - multiple channels
I have 2 watchers, each one creates a socket connection. How to make one connection?
There is a solution to move the connection to the socket into a variable and pass it to Watchers? There is a comment in the code where the socket is connected.
Channels in watchers
export function* watchOnSocketBinanceRT() { while (true) { const { socketToken } = yield take(types.BINANCE_SOCKET_OPEN); const socket = yield call(socketConnectionBinance, socketToken); // Creates a new connection const channel = yield call(socketChannelBinanceRT, socket); if (socket.onopen) { yield put({ type: types.BINANCE_SOCKET_CONNECTED }); } yield fork(socketSendBinance, socket); yield fork(socketCloseBinance, socket); const { cancel } = yield race({ task: call(socketOnmessageBinance, channel), cancel: take(types.BINANCE_SOCKET_CLOSED), }); if (cancel) { buffersRT.flush(); channel.close(); } } } export function* watchOnSocketBinance() { while (true) { const { socketToken } = yield take(types.BINANCE_SOCKET_OPEN); const socket = yield call(socketConnectionBinance, socketToken); // Creates a new connection const channel = yield call(socketChannelBinance, socket); if (socket.onopen) { yield put({ type: types.BINANCE_SOCKET_CONNECTED }); } yield fork(socketSendBinance, socket); yield fork(socketCloseBinance, socket); const { cancel } = yield race({ task: call(socketOnmessageBinance, channel), cancel: take(types.BINANCE_SOCKET_CLOSED), }); if (cancel) { channel.close(); } } }
Socket connection
const socketConnectionBinance = socketToken => { return new Promise((resolve, reject) => { let socket; if (socketToken) { socket = new WebSocket(`${wsUrlBinance()}/${socketToken}`); } else { socket = new WebSocket(`${wsUrlBinance()}`); } socket.onopen = function () { resolve(socket); console.log('Binance connection opened'); }; socket.onerror = function (event) { reject(event); console.log('Binance socket error: ', event); }; socket.onclose = function (event) { if (event.wasClean) { console.log('Binance connection closed'); } }; }); };
Thanks for the help!
-
Error when testing a React search component
Hi I´m getting this TypeError when testing my component, I don't know why the history is undefined
TypeError: Cannot read property 'push' of undefined 16 | e.preventDefault(); 17 | setSearchTerm(inputValue); > 18 | history.push(`/search/${inputValue}`);
here is my component:
const handleSubmit = (e) => { e.preventDefault(); setSearchTerm(inputValue); history.push(`/search/${inputValue}`);
and my test
it("Calls the handleSubmit function", () => { const handleSubmit = jest.fn(); fireEvent.submit(screen.getByRole("textbox")); expect(handleSubmit).toHaveBeenCalled();
-
how properly mock/test constructor with Jest
I'd like to test Module2 constructor as well as other its functions. What is the proper way to mock Module2 constructor without breaking testFunc1, testFunc2 to test with Jest.
// **************************************** // Module 1 component class Module1 { init() { // ........ } } module.exports = new Module1() // **************************************** // Module 2 component const module1 = require('./module1') class Module2 { constructor() { try { module1.init() } catch (err) { console.log('error') process.exit(1) } } testfunc1 = () => { // ........ } testfunc2 = () => { // ........ } } module.exports = new Module2()
-
How do I create a test for my services controller (Jest)?
I'm trying to create a test for my Animals List Services Controller, making sure the database query is tested. Right now with what I have, I have been able to mock the database query call to ensure the query is being called with the right parameters. However, i'm also trying to mock the return values from the database query call. I'm not sure how to mock dbResult in "services.ts" to get the rows property. Please I need some help, not sure how to do it. Thank you in advance.
I believe I was able to mock the database query call, however, is there a way to refactor or create a test to mock the return call of dbResult?
services.ts
import db from '../../modules/db'; import { DBGenericDataResponse } from '../../types/models'; export async function GetAnimalsList(): Promise<DBGenericDataResponse> { const lQuery = `select animalid, description from animal where active=1 order by sortorder, description`; const responseMessage: DBGenericDataResponse = { code: 200, status: 'ok', message: '', count: 0, data: [], error: '' }; try { const dbResult = await db.query<any>(lQuery); responseMessage.message = 'Animals Returned'; responseMessage.count = dbResult.rows.length; responseMessage.data = dbResult.rows; } catch (err) { responseMessage.code = 400; responseMessage.status = 'error'; responseMessage.message = 'Error retrieving Animals List'; responseMessage.error = err; } return responseMessage; }
ServicesTest.spec.ts
import * as Services from '../../../../src/controllers/animals/services'; import db from '../../../../src/modules/db'; describe('GetAnimalsList', () => { afterEach(() => { jest.resetAllMocks(); }); it('should call the database with the correct query parameter', async () => { const dbMock = jest.spyOn(db, 'query'); const response = await Services.GetAnimalsList(); expect(dbMock).toBeCalled(); expect(dbMock).toHaveBeenCalledWith( 'select animalid, description from animal where active=1 order by sortorder, description' ); }); });
-
React unit test: access methods and state props inside functional components with Jest Enzyme
I am trying to learn writing unit tests using jest, enzyme for functional based React components. I am trying to write unit tests for the methods defined inside functional components. Please can anyone help me with this?
Mycomponent:
const MyTable = ({allRows}) => { const [page, setPage] = useState(0); const [val, setVal] = useState(0); const handleClick = (index) => { setPage(index); //other logic }; const handleFilter = (event) => { setVal(0); //other logic } return ( <div className={classes.root}> <Paper className={classes.paper}> <TableContainer> <Table> <TableBody> <TableRow onClick={(event) => handleClick(event, row, index)} > <TableCell> </TableCell> </TableRow> </TableBody> </Table> </TableContainer> </Paper> </div> ); } export default MyTable;
setUpTest.js
// jest-dom adds custom jest matchers for asserting on DOM nodes. // allows you to do things like: // expect(element).toHaveTextContent(/react/i) // learn more: https://github.com/testing-library/jest-dom import '@testing-library/jest-dom'; import {configure} from 'enzyme'; import Adapter from '@wojtekmaj/enzyme-adapter-react-17'; configure({adapter: new Adapter()});
MyTable.test.js
describe('<MyTable />', () => { let wrapper; let mockData = [{ id: 'id1' }, { id: 'id2' }] beforeAll(() => { wrapper = shallow( <MyTable allRows={mockData} />); }); it('handleClick Test', () => { const spy = jest.spyOn(wrapper.instance(), "handleClick"); }); })
ERROR: TypeError: Cannot read property 'handleClick' of null
I also tried to console.log(wrapper.instance()) but it is returning null I also tried to access state props but it says ShallowWrapper::state() can only be called on class components
Any help is appreciated
-
Unhandled error: ,Script error for "enzyme"
I am trying to set up enzyme for React Testing and during the set up it fails with the following error.
Error: Unhandled error: script error for enzyme. Error: Unhandled error: ,Script error for "react", needed by: test/js/steps/test.tsx
Setup: App: MyProj Enzyme: https://github.com/jonmbake/enzyme-umd from this built enzyme-react.js & enzyme-react.min.js (was looking for UMD module) Test Framework: Cucumberjs
test.tsx
import * as React from "react"; import { shallow } from 'enzyme'; import App from "reactui/App"; import { Base } from "reactui/Base"; import chai = require('js/chai'); import control = require('test/js/Control'); var expect = chai.expect; function supWrapper() { Given(/^App is running$/, function () { const wrapper = shallow(<App ag={control.getAg()} />) var agvalue = expect(wrapper.find(Base).prop('ag').props.checked).to.be.not.null; return (agvalue); }); } export = supWrapper;
Where am I going wrong?? Any help appreciated
-
ReactWrapper::state() can only be called on class components
I recently converted my class component to a functional component using React Hooks and now some of my tests are failing. The error I get is:
ReactWrapper::state() can only be called on class components
and I think it's because in my test I use
.state
. Is there an alternative to this so my tests will pass now that I no longer have a class component?it('sets field state isInputActive to true onFocus', () => { const component = mount(<PinInput pin="123" onChange={() => {}} />); expect(component.childAt(0).state('isInputActive')).toEqual(false); component.find('.parental-pin__input-entry').simulate('click'); expect(component.childAt(0).state('isInputActive')).toEqual(true); });