我正在尝试模拟一个函数,以便我可以根据钩子中变量的特定值覆盖分支。
这是我的测试文件
import React from 'react';
import { render, screen, fireEvent, act } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import '@testing-library/jest-dom/extend-expect';
import GamesEngagement from 'pages/Analytics/GamesEngagement';
import { useGetEngagementInsightsQuery } from 'app/services/analytics';
import localStorage from 'utils/localStorage';
import hooks from 'utils/hooks';
jest.mock('components/Charts', () => {
return {
__esModule: true,
default: () => {
return <div data-testid='mocked-charts'></div>;
}
};
});
jest.mock('app/services/analytics', () => ({
useGetEngagementInsightsQuery: jest.fn()
}));
jest.mock('utils/localStorage', () => ({
getPlatform: jest.fn(),
getToken: jest.fn()
}));
// jest.mock('utils/hooks', () => ({
// __esModule: true, // this property makes it work
// useWindowSize: () => [500], // Mock implementation of the hook
// }));
describe(`GamesEngagement Component`, () => {
beforeEach(() => {
useGetEngagementInsightsQuery.mockReturnValue({
data: [{ mark: 'A', engagementRate: 80 }],
isFetching: false
});
});
it(`rendered correctly`, () => {
render(<GamesEngagement />);
expect(screen.getByText('Games engagement rate')).toBeInTheDocument();
});
});
describe(`GamesEngagement Component`, () => {
let openWindowSpy;
beforeEach(() => {
useGetEngagementInsightsQuery.mockReturnValue({
isFetching: false
});
openWindowSpy = jest.spyOn(window, 'open').mockImplementation(() => {});
});
afterEach(() => {
openWindowSpy.mockRestore();
});
it(`rendered correctly`, () => {
render(<GamesEngagement />);
expect(screen.getByText('Games engagement rate')).toBeInTheDocument();
});
it('should open a specific URL when platform is "teams"', () => {
localStorage.getPlatform.mockReturnValue('teams');
const { getByText } = render(<GamesEngagement />);
fireEvent.click(getByText('Start a game'));
expect(openWindowSpy).toHaveBeenCalledWith(
'https://teams.microsoft.com/l/entity/undefined/homeTab',
'_blank'
);
});
it('should open a different URL when platform is not "teams"', () => {
localStorage.getPlatform.mockReturnValue('not-teams');
const { getByText } = render(<GamesEngagement />);
fireEvent.click(getByText('Start a game'));
expect(openWindowSpy).toHaveBeenCalledWith(
`undefined/slack-deeplink?page=gamesPage&key=undefined`,
'_blank'
);
});
});
describe(`GamesEngagement Component`, () => {
beforeEach(() => {
useGetEngagementInsightsQuery.mockReturnValue({
data: [{ mark: 'A', engagementRate: 80 }],
isFetching: true
});
});
it(`rendered correctly`, () => {
render(<GamesEngagement />);
expect(screen.getByText('Games engagement rate')).toBeInTheDocument();
});
it('width is less than 425', () => {
jest.spyOn(hooks, 'useWindowSize').mockImplementation(() => ({width: 400, height: 400}))
render(<GamesEngagement />);
expect(screen.getByTestId('mocked-charts')).toBeInTheDocument();
})
});
这是我面临的错误。
GamesEngagement Component › width is less than 425
Cannot spy the useWindowSize property because it is not a function; undefined given instead
102 |
103 | it('width is less than 425', () => {
> 104 | jest.spyOn(hooks, 'useWindowSize').mockImplementation(() => ({width: 400, height: 400}))
| ^
105 |
106 | render(<GamesEngagement />);
107 | expect(screen.getByTestId('mocked-charts')).toBeInTheDocument();
at ModuleMocker.spyOn (node_modules/jest-mock/build/index.js:798:15)
at Object.<anonymous> (src/test/pages/Analytics/GamesEngagement/index.test.js:104:12)
useWindowSize 函数使用钩子或宽度。我无法获取它的价值。 这就是它在react文件中的使用方式。
const { width } = useWindowSize();
...more code
<Charts
type='line'
labels={width < 425 ? labels.slice(-5) : labels}
datasets={[
{
data: width < 425 ? data.slice(-5) : data,
backgroundColor: '#E1DCFF'
}
]}
...more code
这是 useWindowSize 函数本身
function useWindowSize() {
const [windowSize, setWindowSize] = useState({
width: undefined,
height: undefined
});
useEffect(() => {
function handleResize() {
setWindowSize({
width: window.innerWidth,
height: window.innerHeight
});
}
window.addEventListener('resize', handleResize);
handleResize();
return () => window.removeEventListener('resize', handleResize);
}, []);
return windowSize;
}
export default useWindowSize;
如何正确模拟它以便测试用例通过并增加分支覆盖率?
问题在于您的导入。如果你改变:
import hooks from 'utils/hooks';
到
import * as hooks from 'utils/hooks';
应该可以。
您可以在这些文档中查找导入方式之间的差异:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import