I get an error when testing with jest on code that imports a homegrown library - jestjs

I get an error when testing with jest on code that imports a homegrown library.
Other than jest, the other processes are successful, how can I make the test succeed?
FAIL src/pages/e2e.spec.tsx
● Test suite failed to run
Cannot find module 'components/layout/Layout' from 'src/pages/index.tsx'
Require stack:
src/pages/index.tsx
src/pages/e2e.spec.tsx
> 1 | import { Layout } from 'components/layout/Layout'
| ^
2 | import { HomepageComponent } from 'components/parts/home'
3 | import { useSearchMedicines } from 'hooks/api/product/useSearchMedicines'
4 | import { useRouter } from 'next/router'
at Resolver._throwModNotFoundError (node_modules/jest-resolve/build/resolver.js:427:11)
at Object.<anonymous> (src/pages/index.tsx:1:1)
at Object.<anonymous> (src/pages/e2e.spec.tsx:7:1)
try
commnad:
npm test
code
import { render, screen } from '#testing-library/react'
import userEvent from '#testing-library/user-event'
import { Layout } from 'components/layout/Layout'
import styled from '#emotion/styled'
import { Header } from 'components/parts/common/header'
import { useTranslationText } from 'locale'
import Home from './index'
describe('Home', () => {
it('should display search results', async () => {
// Render the Home component
render(<Home />)
// Search for a new keyword
const searchInput = screen.getByRole('textbox')
userEvent.clear(searchInput)
userEvent.type(searchInput, 'new keyword')
userEvent.click(screen.getByRole('button'))
// Wait for new search results to load
const newMedicineNames = await screen.findAllByTestId('medicine-name')
expect(newMedicineNames.length).greaterThan(0)
expect(newMedicineNames[0]).not.equal(medicineNames[0])
})
})
expect
test success
Test Suites: 0 failed, 1 passed, 1 total
Tests: 0 failed, 1 passed, 1 total

Related

Need to test SwiperJS component and jest throws an error

this is what I have in my test file and have no idea how to fix it was searching everywhere could not find the solution
import { render } from '#testing-library/react';
import { ImageGallery } from '../index';
describe('Swiper has to render', () => {
test('Will Swiper render', () => {
const { asFragment } = render(<ImageGallery />);
expect(asFragment()).toMatchSnapshot();
});
});
having this in my test file
having an error
like that
● Test suite failed to run
Jest encountered an unexpected token
Jest failed to parse a file. This happens e.g. when your code or its dependencies use non-standard JavaScript syntax, or when Jest is not configured to support such syntax.
Out of the box Jest supports Babel, which will be used to transform your files into valid JS based on your Babel configuration.
By default "node_modules" folder is ignored by transformers.
SyntaxError: Unexpected token 'export'
1 | /* eslint-disable import/no-unresolved */
2 | import React, { useState, useCallback } from 'react';
> 3 | import { Swiper, SwiperSlide } from 'swiper/react';
| ^
4 | import ImageViewer from 'react-simple-image-viewer';
5 |
6 | import 'swiper/css/bundle';
at Runtime.createScriptFromCode (node_modules/jest-runtime/build/index.js:1728:14)
at Object.<anonymous> (src/components/ImageGallery/ImageGallery.js:3:1)

How to test a function from a svelte component with jest?

There is a lot of documentation on the internet to test svelte component with jest, calling render functions and simulating browser events. This is nice, but how can I test a function inside a svelte component?
mycompoment.svelte
<script>
function veryComplicated(foo) {
...
}
</script>
<div>...</div>
mycomponent.test.js
import { veryComplicated } from "./mycomponent.svelte"
test('it works', async () => {
expect(vercomplicated("foo").toBe("bar"))
})
jest
FAIL src/mycomponent.test.ts
● Test suite failed to run
src/mycomponent.test.ts:1:10 - error TS2614: Module '"*.svelte"' has no exported member 'veryComplicated'. Did you mean to use 'import veryComplicated from "*.svelte"' instead?
1 import { veryComplicated } from "./mycomponent.svelte"
~~~~~~~~~~~~~~~
Test Suites: 1 failed, 1 total
Tests: 0 total
Snapshots: 0 total
Time: 1.697 s
Ran all test suites.
Adding export before the veryComplicated definition does not help.
How can I test the veryComplicated function?
You can export a function using a module context script block.
<script context="module">
export veryComplicated() {
// ...
}
</script>
<div>...</div>
Then you can do import { veryComplicated } from './mycomponent.svelte' as you were originally trying to do.
https://svelte.dev/tutorial/module-exports
Found it. I had to call render
mycomponent.test.js
import { render } from '#testing-library/svelte'
import MyComponent from "./mycomponent.svelte"
test('it works', async () => {
const component = render(MyComponent)
expect(component.verComplicated("foo").toBe("bar")
})
And it is needed to export the veryComplicated function.

Why I can not use " import { createSlice, configureStore } from '#reduxjs/toolkit' " in Node.js

guys
I am learning redux, and try to run a very simple example code in node.js environment. I got the following error when I try to use :
import { createSlice, configureStore } from '#reduxjs/toolkit' .
The errors is:
import { createSlice, configureStore } from '#reduxjs/toolkit'
^^^^^^^^^^^
SyntaxError: Named export 'createSlice' not found. The requested module '#reduxjs/toolkit' is a CommonJS module, which may not support all module.exports as named exports.
CommonJS modules can always be imported via the default export, for example using:
import pkg from '#reduxjs/toolkit';
const { createSlice, configureStore } = pkg;
at ModuleJob._instantiate (internal/modules/esm/module_job.js:120:21)
at async ModuleJob.run (internal/modules/esm/module_job.js:165:5)
at async Loader.import (internal/modules/esm/loader.js:177:24)
at async Object.loadESM (internal/process/esm_loader.js:68:5)
If I use import like what the error tip says:
import pkg from '#reduxjs/toolkit';
const { createSlice, configureStore } = pkg;
All is OK.
What I want to ask is:
It gives me a wrong example in the official website of Redux? Or Just I run the example with a wrong way?
The following is the detail information.
My Node.js version is: v14.17.3
1 Init a node project:
mkdir redux_01
cd redux_01
yarn init
yarn add #reduxjs/toolkit
2 Modify the 'package.json', add a line in it:
"type":"module"
3 Create a file 'index.js' with the "Redux Toolkit Example" code parsed from https://redux.js.org/introduction/getting-started.
import { createSlice, configureStore } from '#reduxjs/toolkit'
const counterSlice = createSlice({
name: 'counter',
initialState: {
value: 0
},
reducers: {
incremented: state => {
// Redux Toolkit allows us to write "mutating" logic in reducers. It
// doesn't actually mutate the state because it uses the Immer library,
// which detects changes to a "draft state" and produces a brand new
// immutable state based off those changes
state.value += 1
},
decremented: state => {
state.value -= 1
}
}
})
export const { incremented, decremented } = counterSlice.actions
const store = configureStore({
reducer: counterSlice.reducer
})
// Can still subscribe to the store
store.subscribe(() => console.log(store.getState()))
// Still pass action objects to `dispatch`, but they're created for us
store.dispatch(incremented())
// {value: 1}
store.dispatch(incremented())
// {value: 2}
store.dispatch(decremented())
// {value: 1}
4 Now I run it like this:
node index.js
I then got that error message that I just mentioned.
The reason for the error is explained here:
https://lightrun.com/answers/reduxjs-redux-toolkit-cannot-import-redux-toolkit-from-a-nodejs-esm-module "here"
solution:
import * as toolkitRaw from '#reduxjs/toolkit';
const { createSlice,configureStore } = toolkitRaw.default ?? toolkitRaw;
or in Typescript:
import * as toolkitRaw from '#reduxjs/toolkit';

Jest spiedOn method is not called, but called once change the test case order

The Spied on code is not called when the test is at the second position. (or a second render) and test case fails
Test case passes if the test case is at the first position(or on first render).
Using a very basic create-react-app OOTB example and simplifying it even more for a MCVE:
MyModule.js
import React from 'react';
import someClass from './someClass';
function App() {
someClass.track("someevent");
return null;
}
export default App;
someClass.js
class SomeClass {
constructor() {
this.someProp = null;
}
getSatellite() {
return {
track: () => {}
};
}
track(someProp) {
///THIS BELOW IF CLAUSE IS THE PROBLEM
if (this.someProp === someProp) {
return;
} else {
this.someProp = someProp;
}
///////////////////////
this.getSatellite().track('someevent');
}
}
const instance = new SomeClass();
export default instance;
App.js
import React from 'react';
import MyModule from './MyModule'
function App() {
return (
<div className="App">
<MyModule />
</div>
);
}
export default App;
App.test.js
import React from 'react';
import { render } from '#testing-library/react';
import App from './App';
import someClass from './someClass';
test('renders learn react link', () => {
render(<App />);
});
// it works if this test case is first one, weird :-|
test('renders class', () => {
const track = jest.fn();
jest.spyOn(someClass, 'getSatellite').mockImplementation(()=>{
console.log('here i am');
return {
track
}
})
render(<App />);
expect(track).toHaveBeenCalledTimes(1);
});
Output:
✓ renders learn react link (17ms)
✕ renders class (5ms)
● renders class
expect(jest.fn()).toHaveBeenCalledTimes(expected)
Expected number of calls: 1
Received number of calls: 0
18 | })
19 | render(<App />);
> 20 | expect(track).toHaveBeenCalledTimes(1);
| ^
21 | });
22 |
at Object.<anonymous> (src/App.test.js:20:17)
Test Suites: 1 failed, 1 total
Tests: 1 failed, 1 passed, 2 total
Snapshots: 0 total
Time: 10.472s
Let me know if you need anything in the comments.
In the first render(<App />) the someProp of someClass is being set as someevent.
Now in the next render I am only mocking the function call, but not resetting the someProp. That's why the if (this.someProp === someProp) is taking effect.
So I need to reset the someProp to another value or null and it will work fine.

Test callback prop with Enzyme

I have React-Spring animation in my component:
<SpinnerKf state={status} onRest={changeView && status === 'SUCCESS' ? () => changeView(VIEW_MODES.RECEIPT) : null}>
....
</SpinnerKf>
Where I pass function call inside onRest prop - this is the prop from React-Spring Keyframe, which is called after animation end.
How can I cover this with a test? I'm opened for any tricks, just need to avoid complaining in test coverage.
You can use Enzyme to get the SpinnerKf component and then call its onRest property directly.
Here is a simplified example:
code.js
import * as React from 'react';
const SpinnerKf = () => null;
export const Component = () => (<SpinnerKf onRest={() => { return 'does something'; }}/>);
code.test.js
import * as React from 'react';
import { shallow } from 'enzyme';
import { Component } from './code';
test('callback', () => {
const wrapper = shallow(<Component />);
const result = wrapper.find('SpinnerKf').props().onRest();
expect(result).toBe('does something'); // Success!
});
Note that testing the return value or behavior of the callback is optional, as long as it runs during a unit test it will be included in the code coverage report.

Resources