How to test Rive in React 18
michaelrenops opened this issue · comments
Hi,
I'm trying to write a unit test for my code, but it doesn't work.
I got this error:
ReferenceError: IntersectionObserver is not defined
So I tried to write a simple Rive component like this
import React from 'react';
import { render } from '@testing-library/react';
import Rive from 'rive-react';
jest.mock('@rive-app/react-canvas', () => ({
Rive: jest.fn().mockImplementation(() => ({
on: jest.fn(),
stop: jest.fn()
})),
Layout: jest.fn(),
Fit: {
Cover: 'cover'
},
Alignment: {
Center: 'center'
},
EventType: {
Load: 'load'
},
StateMachineInputType: {
Number: 1,
Boolean: 2,
Trigger: 3
}
}));
describe('LoadingAnimation', () => {
it('should render ', () => {
const loadingAnimation = render(
<Rive src={LoadingAnimationAsset)} className="container-styles" />
);
expect(loadingAnimation.firstChild).toHaveClass('container-styles');
});
});
Still got the same error:
ReferenceError: IntersectionObserver is not defined
I've tried to downgrade to
"@rive-app/canvas": "^1.0.82",
"@rive-app/react-canvas": "^3.0.20",
and still no luck
Version used:
"rive-react": "^3.0.21"
"@rive-app/canvas": "^1.0.83",
"@rive-app/react-canvas": "^3.0.23",
Please help.
Kind regards
Michael Reno
Hey @michaelrenops
Try this:
import React from "react";
import { render } from "@testing-library/react";
import Rive from "@rive-app/react-canvas";
jest.mock("@rive-app/canvas", () => ({
Rive: jest.fn().mockImplementation(() => ({
on: jest.fn(),
stop: jest.fn(),
})),
Layout: jest.fn(),
Fit: {
Cover: "cover",
},
Alignment: {
Center: "center",
},
EventType: {
Load: "load",
},
StateMachineInputType: {
Number: 1,
Boolean: 2,
Trigger: 3,
},
}));
describe("LoadingAnimation", () => {
beforeEach(() => {
global.IntersectionObserver = jest.fn(() => ({
disconnect: jest.fn(),
observe: jest.fn(),
takeRecords: jest.fn(),
unobserve: jest.fn(),
}));
});
it("should render ", () => {
const loadingAnimation = render(
<Rive src={"https://test/file.riv"} className="container-styles" />
);
expect(
loadingAnimation.container.querySelector(".container-styles")
).toBeInTheDocument();
});
});
We do something similar in our own unit tests
Hi @avivian
Thank you for the answer
Unfortunately the global.IntersectionObserver
gave me this error, but the test passes
Type 'Mock<{ disconnect: Mock<any, any>; observe: Mock<any, any>; takeRecords: Mock<any, any>; unobserve: Mock<any, any>; }, []>' is not assignable to type '{ new (callback: IntersectionObserverCallback, options?: IntersectionObserverInit | undefined): IntersectionObserver; prototype: IntersectionObserver; }'.
Type '{ disconnect: Mock<any, any>; observe: Mock<any, any>; takeRecords: Mock<any, any>; unobserve: Mock<any, any>; }' is missing the following properties from type 'IntersectionObserver': root, rootMargin, thresholdsts(2322)
So I did this
class IntersectionObserverStub {
disconnect() {
/* implementation is ignored */
} // stub method
observe() {
/* implementation is ignored */
} // stub method
takeRecords() {
/* implementation is ignored */
} // stub method
unobserve() {
/* implementation is ignored */
} // stub method
}
and this
beforeEach(() => {
jest.doMock('intersection-observer-mock', () => IntersectionObserverStub, { virtual: true });
global.IntersectionObserver = jest.requireMock('intersection-observer-mock');
jest.spyOn(IntersectionObserver.prototype, 'disconnect').mockImplementation();
jest.spyOn(IntersectionObserver.prototype, 'observe').mockImplementation();
jest.spyOn(IntersectionObserver.prototype, 'takeRecords').mockImplementation();
jest.spyOn(IntersectionObserver.prototype, 'unobserve').mockImplementation();
});
It works now.
Thankyou so much.
Kind regards
Michael Reno