英文:
Mock windows media to test responsive hook
问题
I'm here to help with the translation. Here's the code you provided in Chinese:
我正在尝试测试以下实现。
import React from "react";
import { useMediaQuery } from "react-responsive";
const MyComponent = () => {
const isSM = useMediaQuery({ maxWidth: 767 });
const isMD = useMediaQuery({ minWidth: 768, maxWidth: 1023 });
const isLG = useMediaQuery({ minWidth: 1024 });
console.log(`isSM:${isSM} isMD:${isMD} isLG:${isLG}`);
return <>{`isSM:${isSM} isMD:${isMD} isLG:${isLG}`}</>;
};
export default MyComponent;
如何模拟以使isLG可以设置为true?以及类似地,如何能够在其他测试中将isSM和isMD设置为true?
尝试了以下方法,但所有三个(isSM,isMD,isLG)始终为false。
function mockMatchMedia(query) {
return Object.defineProperty(window, 'matchMedia', {
writable: true,
value: jest.fn().mockImplementation((mediaQuery) => ({
matches: mediaQuery.includes(query),
media: mediaQuery,
onchange: null,
addListener: jest.fn(),
removeListener: jest.fn(),
addEventListener: jest.fn(),
removeEventListener: jest.fn(),
dispatchEvent: jest.fn(),
})),
});
}
test("渲染组件", () => {
mockMatchMedia('min-width: 1024px');
mount(<MyComponent />);
// 组件中的控制台日志始终为false。
// 预期isLG为true。
// 断言
}
更新:
以下仍然对所有3个打印false。
import renderer from "react-test-renderer";
import { MatchMediaMock, create } from 'match-media-mock';
export const matchSnapshot = (reactElement: React.ReactElement) => {
const instance = renderer.create(reactElement);
const tree = instance.toJSON();
expect(tree).toMatchSnapshot();
};
interface MockWindow extends Window {
matchMedia: MatchMediaMock
}
test("渲染", () => {
global.window.matchMedia = create();
(window as unknown as MockWindow).matchMedia.setConfig({
type: 'screen',
width: 700
})
matchSnapshot(
<MyComponent />
);
});
如果需要进一步帮助,请告诉我。
英文:
I am trying to test the following implementation.
import React from "react";
import { useMediaQuery } from "react-responsive";
const MyComponent = () => {
const isSM = useMediaQuery({ maxWidth: 767 });
const isMD = useMediaQuery({ minWidth: 768, maxWidth: 1023 });
const isLG = useMediaQuery({ minWidth: 1024 });
console.log(`isSM:${isSM} isMD:${isMD} isLG:${isLG}`);
return <>{`isSM:${isSM} isMD:${isMD} isLG:${isLG}`}</>;
};
export default MyComponent;
How can I mock it so that isLG can be set to true?
And similarly to be able to set isSM and isMD to be true for other tests?
Tried the following but all 3 (isSM, isMD, isLG) are always false.
function mockMatchMedia(query) {
return Object.defineProperty(window, 'matchMedia', {
writable: true,
value: jest.fn().mockImplementation((mediaQuery) => ({
matches: mediaQuery.includes(query),
media: mediaQuery,
onchange: null,
addListener: jest.fn(),
removeListener: jest.fn(),
addEventListener: jest.fn(),
removeEventListener: jest.fn(),
dispatchEvent: jest.fn(),
})),
});
}
test("renders the component", () => {
mockMatchMedia('min-width: 1024px');
mount(<MyComponent />);
// the console log in component prints false for all wrongly.
// Was expecting isLG to be true.
// assertions
}
UPDATE:
The following still prints out false for all 3.
import renderer from "react-test-renderer";
import { MatchMediaMock, create } from 'match-media-mock';
export const matchSnapshot = (reactElement: React.ReactElement) => {
const instance = renderer.create(reactElement);
const tree = instance.toJSON();
expect(tree).toMatchSnapshot();
};
interface MockWindow extends Window {
matchMedia: MatchMediaMock
}
test("renders", () => {
global.window.matchMedia = create();
(window as unknown as MockWindow).matchMedia.setConfig({
type: 'screen',
width: 700
})
matchSnapshot(
<MyComponent />
);
});
答案1
得分: 1
以下是翻译好的内容:
"The match-media-mock package can help you to create the mock for window.matchMedia
easily.
例如:
jest.setup.js
:
import matchMediaMock from 'match-media-mock';
global.window.matchMedia = matchMediaMock.create();
jest.config.js
:
module.exports = {
preset: 'ts-jest/presets/js-with-ts',
testEnvironment: 'jsdom',
setupFilesAfterEnv: ['jest-extended', './jest.setup.js']
};
index.tsx
:
import React from "react";
import { useMediaQuery } from "react-responsive";
const MyComponent = () => {
const isSM = useMediaQuery({ maxWidth: 767 });
const isMD = useMediaQuery({ minWidth: 768, maxWidth: 1023 });
const isLG = useMediaQuery({ minWidth: 1024 });
console.log(`isSM:${isSM} isMD:${isMD} isLG:${isLG}`);
return <>{`isSM:${isSM} isMD:${isMD} isLG:${isLG}`}</>;
};
export default MyComponent;
1. 使用RTL进行测试的示例:
index.test.tsx
:
import React from 'react';
import { render } from '@testing-library/react';
import { MatchMediaMock } from 'match-media-mock';
import MyComponent from '.';
interface MockWindow extends Window {
matchMedia: MatchMediaMock
}
describe('76305067', () => {
test('应该是sm', () => {
(window as unknown as MockWindow).matchMedia.setConfig({
type: 'screen',
width: 700,
})
render(<MyComponent />)
})
test('应该是md', () => {
(window as unknown as MockWindow).matchMedia.setConfig({
type: 'screen',
width: 1000,
})
render(<MyComponent />)
})
test('应该是lg', () => {
(window as unknown as MockWindow).matchMedia.setConfig({
type: 'screen',
width: 1200,
})
render(<MyComponent />)
})
})
测试结果:
PASS stackoverflow/76305067/index.test.tsx (18.06 s)
76305067
✓ 应该是sm (54 ms)
✓ 应该是md (7 ms)
✓ 应该是lg (5 ms)
console.log
isSM:true isMD:false isLG:false
at MyComponent (stackoverflow/76305067/index.tsx:9:11)
console.log
isSM:false isMD:true isLG:false
at MyComponent (stackoverflow/76305067/index.tsx:9:11)
console.log
isSM:false isMD:false isLG:true
at MyComponent (stackoverflow/76305067/index.tsx:9:11)
Test Suites: 1 passed, 1 total
Tests: 3 passed, 3 total
Snapshots: 0 total
Time: 19.631 s, estimated 24 s
2. 使用react-dom
进行测试的示例:
import React from 'react';
import { unmountComponentAtNode, render } from 'react-dom';
import { MatchMediaMock } from 'match-media-mock';
import MyComponent from '.';
interface MockWindow extends Window {
matchMedia: MatchMediaMock
}
describe('76305067', () => {
let container: HTMLDivElement | null = null;
beforeEach(() => {
container = document.createElement("div");
document.body.appendChild(container);
});
afterEach(() => {
if (container) {
unmountComponentAtNode(container);
container.remove();
container = null;
}
});
test('应该是sm', () => {
(window as unknown as MockWindow).matchMedia.setConfig({
type: 'screen',
width: 700,
})
render(<MyComponent />, container)
})
test('应该是md', () => {
(window as unknown as MockWindow).matchMedia.setConfig({
type: 'screen',
width: 1000,
})
render(<MyComponent />, container)
})
test('应该是lg', () => {
(window as unknown as MockWindow).matchMedia.setConfig({
type: 'screen',
width: 1200,
})
render(<MyComponent />, container)
})
})
包版本:
"react-responsive": "^9.0.2",
"match-media-mock": "^0.1.1",
"jest": "^26.6.3",
"react": "^16.14.0",
"react-dom": "^16.14.0",
"@testing-library/react": "^11.2.7",
英文:
The match-media-mock package can help you to create the mock for window.matchMedia
easily.
E.g.
jest.setup.js
:
import matchMediaMock from 'match-media-mock';
global.window.matchMedia = matchMediaMock.create();
jest.config.js
:
module.exports = {
preset: 'ts-jest/presets/js-with-ts',
testEnvironment: 'jsdom',
setupFilesAfterEnv: ['jest-extended', './jest.setup.js']
};
index.tsx
:
import React from "react";
import { useMediaQuery } from "react-responsive";
const MyComponent = () => {
const isSM = useMediaQuery({ maxWidth: 767 });
const isMD = useMediaQuery({ minWidth: 768, maxWidth: 1023 });
const isLG = useMediaQuery({ minWidth: 1024 });
console.log(`isSM:${isSM} isMD:${isMD} isLG:${isLG}`);
return <>{`isSM:${isSM} isMD:${isMD} isLG:${isLG}`}</>;
};
export default MyComponent;
1. Testing recipe using RTL:
index.test.tsx
:
import React from 'react';
import { render } from '@testing-library/react';
import { MatchMediaMock } from 'match-media-mock';
import MyComponent from '.';
interface MockWindow extends Window {
matchMedia: MatchMediaMock
}
describe('76305067', () => {
test('should be sm', () => {
(window as unknown as MockWindow).matchMedia.setConfig({
type: 'screen',
width: 700,
})
render(<MyComponent />)
})
test('should be md', () => {
(window as unknown as MockWindow).matchMedia.setConfig({
type: 'screen',
width: 1000,
})
render(<MyComponent />)
})
test('should be lg', () => {
(window as unknown as MockWindow).matchMedia.setConfig({
type: 'screen',
width: 1200,
})
render(<MyComponent />)
})
})
Test result:
PASS stackoverflow/76305067/index.test.tsx (18.06 s)
76305067
✓ should be sm (54 ms)
✓ should be md (7 ms)
✓ should be lg (5 ms)
console.log
isSM:true isMD:false isLG:false
at MyComponent (stackoverflow/76305067/index.tsx:9:11)
console.log
isSM:false isMD:true isLG:false
at MyComponent (stackoverflow/76305067/index.tsx:9:11)
console.log
isSM:false isMD:false isLG:true
at MyComponent (stackoverflow/76305067/index.tsx:9:11)
Test Suites: 1 passed, 1 total
Tests: 3 passed, 3 total
Snapshots: 0 total
Time: 19.631 s, estimated 24 s
2. Testing recipe using react-dom
:
import React from 'react';
import { unmountComponentAtNode, render } from 'react-dom';
import { MatchMediaMock } from 'match-media-mock';
import MyComponent from '.';
interface MockWindow extends Window {
matchMedia: MatchMediaMock
}
describe('76305067', () => {
let container: HTMLDivElement | null = null;
beforeEach(() => {
container = document.createElement("div");
document.body.appendChild(container);
});
afterEach(() => {
if (container) {
unmountComponentAtNode(container);
container.remove();
container = null;
}
});
test('should be sm', () => {
(window as unknown as MockWindow).matchMedia.setConfig({
type: 'screen',
width: 700,
})
render(<MyComponent />, container)
})
test('should be md', () => {
(window as unknown as MockWindow).matchMedia.setConfig({
type: 'screen',
width: 1000,
})
render(<MyComponent />, container)
})
test('should be lg', () => {
(window as unknown as MockWindow).matchMedia.setConfig({
type: 'screen',
width: 1200,
})
render(<MyComponent />, container)
})
})
package versions:
"react-responsive": "^9.0.2",
"match-media-mock": "^0.1.1",
"jest": "^26.6.3",
"react": "^16.14.0",
"react-dom": "^16.14.0",
"@testing-library/react": "^11.2.7",
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论