Open TD-DO opened 1 year ago
I have a very similar issue revolving around calling the cleanup() function. For many test runners, cleanup() gets called automatically. @TD-DO you have cleanup() in your stack trace. When I disable the automatic cleanup call, my code works fine. (my error message is:
'this.node.getScreenCTM is not a function'
You can disable automatic calling of cleanup by importing:
import '@testing-library/react/dont-cleanup-after-each';
But even if you do this, and you call cleanup yourself:
afterEach(cleanup);
(I'm using jest)
You will still get the same error. I can get around this by doing:
afterEach(() => { setTimeout(() => { cleanup(); }, 1); });
@rodpatulski Thank you for your response! I put import '@testing-library/react/dont-cleanup-after-each';
in the file that is breaking and unfortunately it is still breaking and in the same way. Which is weird because, as you say, I have cleanup in my stack trace so it seems like this would fix it. I also tested adding afterEach(() => { setTimeout(() => { cleanup(); }, 1); });
to the file and it didn't fix anything.
@TD-DO what is your react version?
@rodpatulski 18.2.0
I think you're having a problem with the way the root is constructed in react 18, try react 17 and see if it works.
Do you mean in order to troubleshoot it? Because I can't permanently switch to react 17, my devops team is adamant we stay on 18.
i solved this problem adding after imports and before the describe/test this:
jest.mock('react-apexcharts', () => ({ __esModule: true, default: () => <div /> }));
like this
:)
Thank you! That does make it possible to test my other parts of the component without breaking but I was hoping there would be some way around mocking the library because I want to know when and if the library has breaking changes.
@sohail-coder Not really. I'm mocking out the module at the moment but I'd prefer to be able to test without mocking
Yes, just to see if this is the issue.
On Thu, Aug 25, 2022, 2:19 PM Tara Dia @.***> wrote:
Do you mean in order to troubleshoot it? Because I can't permanently switch to react 17, my devops team is adamant we stay on 18.
— Reply to this email directly, view it on GitHub https://github.com/apexcharts/react-apexcharts/issues/425#issuecomment-1227772510, or unsubscribe https://github.com/notifications/unsubscribe-auth/AGLLSCOIEKXWDDE7UIUZVM3V27PNRANCNFSM57BQRHBQ . You are receiving this because you were mentioned.Message ID: @.***>
@rodpatulski Unfortunately I am getting the same bug
Awesome! I can also confirm that mocking the module as @oswmoena described works to solve this issue 👍🏻 all Jest tests are passing so it's a viable stopgap until the issue is fixed natively.
I am getting the same bug and the fix @oswmoena posted does not work for me either
I am having the same issue. I am using React 18, React-Testing Library, and Jest.
The issue I'm running into, with v1.4.0, is that when I run the "render" function from react testing library:
render(
<div className="mixed-chart">
<Chart
options={this.state.options}
series={this.state.series}
type="bar"
width="500"
/>
</div>
);
The Chart component is coming back as a Element Type error and as a plain object, and not of a React type.
same issue here, did some one already solved?
My team is also having this issue. We are unable to get react-apexcharts
to be able to clean up after any jest test using react testing library. Has anyone found a solution?
You might be needing to mock or polyfill ResizeObserver.
Take a look at this issue with possible solutions: https://github.com/jsdom/jsdom/issues/3368.
finally I found solution to solve full rendering of apexchart includes testing. Referring to this site: https://stackoverflow.com/questions/67209367/typeerror-r-node-getbbox-is-not-a-function-code-err-unhandled-rejection
Object.defineProperty(window, 'ResizeObserver', {
writable: true,
value:
window.ResizeObserver
|| jest.fn().mockImplementation(() => ({
observe: jest.fn(),
unobserve: jest.fn(),
disconnect: jest.fn()
}))
});
Object.defineProperty(global.SVGElement.prototype, 'getScreenCTM', {
writable: true,
value: jest.fn(),
});
Object.defineProperty(global.SVGElement.prototype, 'getBBox', {
writable: true,
value: jest.fn().mockReturnValue({
x: 0,
y: 0,
}),
});
Object.defineProperty(global.SVGElement.prototype, 'getComputedTextLength', {
writable: true,
value: jest.fn().mockReturnValue(0),
});
Object.defineProperty(global.SVGElement.prototype, 'createSVGMatrix', {
writable: true,
value: jest.fn().mockReturnValue({
x: 10,
y: 10,
inverse: () => {},
multiply: () => {},
}),
});
finally I found solution to solve full rendering of apexchart includes testing. Referring to this site: https://stackoverflow.com/questions/67209367/typeerror-r-node-getbbox-is-not-a-function-code-err-unhandled-rejection
Object.defineProperty(window, 'ResizeObserver', {
writable: true,
value:
window.ResizeObserver
|| jest.fn().mockImplementation(() => ({
observe: jest.fn(),
unobserve: jest.fn(),
disconnect: jest.fn()
}))
});
Object.defineProperty(global.SVGElement.prototype, 'getScreenCTM', {
writable: true,
value: jest.fn(),
});
Object.defineProperty(global.SVGElement.prototype, 'getBBox', {
writable: true,
value: jest.fn().mockReturnValue({
x: 0,
y: 0,
}),
});
Object.defineProperty(global.SVGElement.prototype, 'getComputedTextLength', {
writable: true,
value: jest.fn().mockReturnValue(0),
});
Object.defineProperty(global.SVGElement.prototype, 'createSVGMatrix', {
writable: true,
value: jest.fn().mockReturnValue({
x: 10,
y: 10,
inverse: () => {},
multiply: () => {},
}),
});
I had to modify the solution from @spanwair slightly to get the charts to render in jest + React Testing Library + JSDOM. I think apexcharts needs getBBox
to return a width and height also. Here's the solution that I used:
import ResizeObserver from "resize-observer-polyfill";
window.ResizeObserver = ResizeObserver;
Object.defineProperty(global.SVGElement.prototype, "getScreenCTM", {
writable: true,
value: jest.fn(),
});
Object.defineProperty(global.SVGElement.prototype, "getBBox", {
writable: true,
value: jest.fn().mockReturnValue({
x: 10,
y: 10,
width: 100,
height: 100,
}),
});
Object.defineProperty(global.SVGElement.prototype, "getComputedTextLength", {
writable: true,
value: jest.fn().mockReturnValue(10),
});
Object.defineProperty(global.SVGElement.prototype, "createSVGMatrix", {
writable: true,
value: jest.fn().mockReturnValue({
x: 10,
y: 10,
inverse: () => {},
multiply: () => {},
}),
});
Thank you @mterrel and @spanwair for the mock examples, these have worked for me!
However I am using vitest, so here's my mock setup if it's of use to anyone.
import { vi } from 'vitest';
const ResizeObserver = vi.fn(() => ({
observe: vi.fn(),
unobserve: vi.fn(),
disconnect: vi.fn(),
}));
const SVGElement = vi.fn(() => ({
getScreenCTM: vi.fn(() => ({
writable: true,
value: vi.fn(),
})),
getBBox: vi.fn(() => ({
writable: true,
value: vi.fn().mockReturnValue({
x: 10,
y: 10,
width: 100,
height: 100,
}),
})),
getComputedTextLength: vi.fn(() => ({
writable: true,
value: vi.fn().mockReturnValue(10),
})),
createSVGMatrix: vi.fn(() => ({
writable: true,
value: vi.fn().mockReturnValue({
x: 10,
y: 10,
inverse: vi.fn(),
multiply: vi.fn(),
}),
})),
}));
vi.stubGlobal('ResizeObserver', ResizeObserver);
vi.stubGlobal('SVGElement', SVGElement);
Also, I am running snapshot tests and needed constant "unique" ids, apexcharts use Math.random() for their unique ids. Here is the mock:
beforeEach(() => {
// Mock Math.random to always return a fixed value
vi.spyOn(Math, 'random').mockReturnValue(0.9);
});
afterEach(() => {
// Restore the original Math.random function
vi.restoreAllMocks();
});
Add the following after the imports:
jest.mock("react-apexcharts", () => ({
__esModule: true,
default: () => <div />,
}))
I used your example code to create a chart and used react testing library to simply render it and I got nothing but error messages.
The code (called fake.js):
The test:
The error (it overflowed so I got as much as I could):
Obviously I don't care about making this contrived example work, but I'm concerned that I can't test the parts of my code that contain an apexchart without mocking out the apexchart. Is there a better way around this?