Enzyme/Jest: How to test if mocked function has been called - javascript

I'm trying to test for the call of fetch() inside of my changeIt() function using jest/enzyme.
But obviously I'm doing something wrong:
example.js
import fetch from 'node-fetch'
export default class Example extends Component {
changeIt (id, value) {
fetch('http://localhost/set-status?id=' + id + '&value=' + value)
}
render () {
return (
<div>something </div>
)
}
}
example.test.js
jest.mock('node-fetch')
test('should call fetch()', () => {
const id = 1
const value = 50
const fetch = jest.fn() // <- This is wrong
const wrapper = shallow(<Example />)
wrapper.instance().changeIt(id, value)
expect(fetch).toHaveBeenCalled() // <- This is wrong
})

You need to properly mock the node-fetch module. Because it is in node_modules, you need to put node-fetch inside a __mocks__ folder on the same level as node_modules like:
├── node_modules/
│ ├── node-fetch/
├── __mocks__/
│ ├── node-fetch.js
Inside node-fetch.js put:
export default jest.fn();
Finally import fetch in your test file and mock it like this:
import Example from './Bla';
import { shallow } from 'enzyme';
import React from 'react';
import fetch from 'node-fetch';
/**
* Important! Import the mocked function.
* Start the mocking with jest.mock('node-fetch').
* Stop the mocking with jest.unmock('node-fetch').
*/
jest.mock('node-fetch');
test('should call fetch()', () => {
const id = 1
const value = 50
const wrapper = shallow(<Example />)
wrapper.instance().changeIt(id, value)
expect(fetch).toHaveBeenCalled() // now it works
})
Read more about mocking node_modules packages in jest here.

Related

Problems with circular imports using index.js?

Given the following file structure:
myFiles
├── index.js
├── getTrue.js
└── dependentGetFalse.js
And the following code
// index.js
export { getTrue } from './getTrue'
export { dependentGetFalse } from './dependentGetFalse'
// getTrue.js
export const getTrue = () => true
// dependentGetFalse.js
import { getTrue } from '.'
export const dependentGetFalse = () => !getTrue()
Where there's (what I assume to be) a circular import between dependentGetFalse.js and index.js.
What problems will arise from this? Or is it ok to have?
If your codes run flawless and you are comfortable with them, It is ok to have this circular situation
It's best to avoid using '.' imports.
Try this:
// dependentGetFalse.js
import { getTrue } from './getTrue'
export const dependentGetFalse = () => !getTrue()
index.js is useful when you try to import something from outside of this folder.

cannot import electron in react componment for ipcRenderer

So I am trying to import the ipcRenderer into a react component to communicate with the electron side. The issue is I cannot import electron. I tried
import { ipcRenderer } from 'electron/renderer'
returns module electron/renderer not found
import { ipcRenderer } from 'electron'
returns fs.existsSync is not a function
const renderer = require('electron');
returns fs.existsSync is not a function
const renderer = require('electron').ipcRenderer;
returns fs.existsSync is not a function
const renderer = window.require('electron');
returns window.require is not a function
I do not know what to do anymore, I have tried everything
I got it! using electron-react-bolierplate they prepared a custom preload.js script that exposes three functions to the rendered components: myPing: (Just a demo, send a ping message to the console) and exposes the on and once ipcRenderer methods
import { Component } from 'react';
...
...
class Hello extends Component {
componentDidMount() {
console.log('Mounted!', 'Window', window, 'electronApi', window.electron, 'ipcRenderer', window.electron.ipcRenderer);
window.electron.ipcRenderer.on('ipc-example', (arg) => {
// eslint-disable-next-line no-console
console.log(arg);
});
window.electron.ipcRenderer.myPing();
}
render() {
return (
<div>
...
...
I used to have same problem. You should not import electron directly inside your renderer/react component. Instead in your preload.ts file you are given some basic configuration by electron-react-bolierplate to use.
So inside your react component you should use window.electron.ipcRenderer.on('channel-name', args) sample below
const myEventHandler = () => {
window.electron.ipcRenderer.on('channel-name', (event, data) => {
console.log('data, event', data, event);
});
};
window.electron, here electron is the name given in preload.ts file. contextBridge.exposeInMainWorld('electron', {...})

NodeJS - Import order

I do not understand how nodejs resolves import statements. I constantly get the cannot import before initialization error.
For example, I have a init module, which exports an async function and a couple of constants that it creates.
import init, { DATA_VALIDATION_POOL, QUEUE_POOL, IS_REPLAY_POOL } from './init.js';
and then app.js waits for the init function to run. init.js itself has imports as well, and some of them resolve and some of them fail. I do not understand why some fail and some import properly.
In this example, everything to the point of importing from ./utils/pool.js is working fine, but for whatever reason, it cannot import the contents of ./utils/dash.js.
./utils/dash.js doesn't import anything from ../init.js
init.js
...
// CREATE POOLS
...
export const QUEUE_POOL = createPool('QUEUE_POOL');
// EMOJI INTERACTIONS
...
registerEmojiInteraction(QUEUE_POOL, {
...
onAdd: goToPrevPage,
});
const init = async () => {
...
await createCoaches(allCoachIds);
};
import { rankEmojis, raceEmojis, vsRaceEmojis } from './Emojis.js';
import { registerEmojiInteraction, onAddHelper } from './utils/emojiInteraction.js';
import { createPool } from './utils/pool.js';
import {
finishedCoachingStudent,
goToPrevPage,
selectStudent,
goToNextPage,
} from './utils/dash.js';
import { createCoaches } from './utils/coach.js';
export default init;

Test with toJson and without it

import React from 'react'
import toJson from 'enzyme-to-json'
import {ScreensCreateAccount} from './CreateAccount'
describe('Testing CreateAccount Component', () => {
const props = {
auth: {
isAuth: false,
isLoadding: false
}
}
it('should render correctly', () => {
const wrapper = shallow(<ScreensCreateAccount {...props}/>)
expect(toJson(wrapper)).toMatchSnapshot()
})
})
I have this test for my component CreateAccount, and i want to know if is necessary to use expect(toJson(wrapper)).toMatchSnapshot() or using just
expect(wrapper).toMatchSnapshot() is correct too. Both implementation build a folder with snapshots with file CreateAccount.test.js.snap. Whats is the diference?
Enzyme-to-json serializes component, created by Enzyme. If your tests work without it, then you have it already configured in jest configuration file.
If no, you can add this to package.json to work:
"jest": {
"snapshotSerializers": ["enzyme-to-json/serializer"]
}

Javascript es6 re-exports

EDIT
Maybe I found the problem, would like if someone could confirm the situation: It seems like test.js is importing index.js which is importing test.js, and export has not an stop infinite-loop inclusion... Is it right? Is there any workaround like Don't include this file if it's the calling one?
I'm facing a strange problem. I'm trying to import some objects from a re-export (tcomb-react-native is not relevant here as the problem is with import/export).
|-- index.js
|-- simpleTypes.js
|-- userType.js
index.js:
export { UserType, UserTypeBase } from './test';
export { TextMax9Type } from './simpleTypes';
simpleTypes.js:
import t from 'tcomb-form-native';
export const TextMax9Type = t.refinement(t.String, s => s.length <= 9);
test.js:
import t from 'tcomb-form-native';
// import { TextMax9Type } from './'; // <----- NOT WORKING!
import { TextMax9Type } from './simpleTypes'; // <----- OK no error
export const UserTypeBase = {
Name: TextMax9Type,
Surname: TextMax9Type,
};
export const UserType = t.struct(UserTypeBase);
NOT WORKING error:
Invalid argument props {} supplied to struct(props, [name]) combinator (expected a dictionary String-> Type)
So which is the problem with re-export that is exporting an empty object?

Categories

Resources