React-bootstrap Typeahead 不适用于 Jest 快照
React-bootstrap Typeahead does not work with Jest snapshots
我有一个来自 API 文档的非常简单的 AsyncTypeahead 示例:
import {AsyncTypeahead} from "react-bootstrap-typeahead";
import React, {Component} from "react";
class AsyncTest extends Component<Props, State> {
constructor() {
super()
this.state = {
isLoading:false,
options:{}
}
}
render() {
return <AsyncTypeahead
disabled={true}
isLoading={this.state.isLoading}
onSearch={query => {
this.setState({isLoading: true});
fetch(`https://api.github.com/search/users?q=123`)
.then(resp => resp.json())
.then(json => this.setState({
isLoading: false,
options: json.items,
}));
}}
options={this.state.options}
/>
}
}
export default AsyncTest;
现在,如果我想为这个组件创建一个 Jest 快照测试,那么我会这样写:
import React from 'react';
import renderer from "react-test-renderer";
import AsyncTest from "./AsyncTest";
describe('Async Test', () => {
test('test', () => {
const test= <AsyncTest/>
expect(renderer.create(test).toJSON()).toMatchSnapshot();
});
});
这不起作用。我收到此错误:
TypeError: Cannot read property 'style' of null
at Window.getComputedStyle (A:\frontend\node_modules\jest-environment-jsdom\node_modules\jsdom\lib\jsdom\browser\Window.js:524:20)
at copyStyles (A:\frontend\node_modules\react-bootstrap-typeahead\lib\containers\hintContainer.js:61:27)
at HintedInput.componentDidMount (A:\frontend\node_modules\react-bootstrap-typeahead\lib\containers\hintContainer.js:113:9)
at commitLifeCycles (A:\frontend\node_modules\react-test-renderer\cjs\react-test-renderer.development.js:10930:22)
这是 bootstrap typeahead 的已知问题吗?
有同样的问题,这是我的解决方案。
罪魁祸首是 typeahead 的 Hintcontainer,特别是这个函数:
function copyStyles(inputNode, hintNode) {
var inputStyle = window.getComputedStyle(inputNode);
/* eslint-disable no-param-reassign */
hintNode.style.borderStyle = interpolateStyle(inputStyle, 'border', 'style');
hintNode.style.borderWidth = interpolateStyle(inputStyle, 'border', 'width');
hintNode.style.fontSize = inputStyle.fontSize;
hintNode.style.lineHeight = inputStyle.lineHeight;
hintNode.style.margin = interpolateStyle(inputStyle, 'margin');
hintNode.style.padding = interpolateStyle(inputStyle, 'padding');
/* eslint-enable no-param-reassign */
}
createMockNode 问题:来自 inputNode 的样式不是普通对象,而是一个
CSSStyleDeclaration,我没有费心去完全模拟它。
https://developer.mozilla.org/en-US/docs/Web/API/CSSStyleDeclaration
因此,使用 window.getComputedStyle 在与普通对象交换时不起作用。
对我来说最简单的解决方案是也模拟 window.getComputedStyle。
因此,第一部分是模拟触发错误的 getComputedStyle 函数。
global.window.getComputedStyle = jest.fn(x=>({}));
但是仍然需要createNodeMock来为输入节点提供一个空的样式对象。
TLDR;快照适用于此代码段
global.window.getComputedStyle = jest.fn(x=>({}));
const createNodeMock = (element) => ({
style: {},
});
const options={createNodeMock};
const tree = renderer
.create(form,options)
.toJSON();
我有一个来自 API 文档的非常简单的 AsyncTypeahead 示例:
import {AsyncTypeahead} from "react-bootstrap-typeahead";
import React, {Component} from "react";
class AsyncTest extends Component<Props, State> {
constructor() {
super()
this.state = {
isLoading:false,
options:{}
}
}
render() {
return <AsyncTypeahead
disabled={true}
isLoading={this.state.isLoading}
onSearch={query => {
this.setState({isLoading: true});
fetch(`https://api.github.com/search/users?q=123`)
.then(resp => resp.json())
.then(json => this.setState({
isLoading: false,
options: json.items,
}));
}}
options={this.state.options}
/>
}
}
export default AsyncTest;
现在,如果我想为这个组件创建一个 Jest 快照测试,那么我会这样写:
import React from 'react';
import renderer from "react-test-renderer";
import AsyncTest from "./AsyncTest";
describe('Async Test', () => {
test('test', () => {
const test= <AsyncTest/>
expect(renderer.create(test).toJSON()).toMatchSnapshot();
});
});
这不起作用。我收到此错误:
TypeError: Cannot read property 'style' of null
at Window.getComputedStyle (A:\frontend\node_modules\jest-environment-jsdom\node_modules\jsdom\lib\jsdom\browser\Window.js:524:20) at copyStyles (A:\frontend\node_modules\react-bootstrap-typeahead\lib\containers\hintContainer.js:61:27) at HintedInput.componentDidMount (A:\frontend\node_modules\react-bootstrap-typeahead\lib\containers\hintContainer.js:113:9) at commitLifeCycles (A:\frontend\node_modules\react-test-renderer\cjs\react-test-renderer.development.js:10930:22)
这是 bootstrap typeahead 的已知问题吗?
有同样的问题,这是我的解决方案。 罪魁祸首是 typeahead 的 Hintcontainer,特别是这个函数:
function copyStyles(inputNode, hintNode) {
var inputStyle = window.getComputedStyle(inputNode);
/* eslint-disable no-param-reassign */
hintNode.style.borderStyle = interpolateStyle(inputStyle, 'border', 'style');
hintNode.style.borderWidth = interpolateStyle(inputStyle, 'border', 'width');
hintNode.style.fontSize = inputStyle.fontSize;
hintNode.style.lineHeight = inputStyle.lineHeight;
hintNode.style.margin = interpolateStyle(inputStyle, 'margin');
hintNode.style.padding = interpolateStyle(inputStyle, 'padding');
/* eslint-enable no-param-reassign */
}
createMockNode 问题:来自 inputNode 的样式不是普通对象,而是一个
CSSStyleDeclaration,我没有费心去完全模拟它。
https://developer.mozilla.org/en-US/docs/Web/API/CSSStyleDeclaration
因此,使用 window.getComputedStyle 在与普通对象交换时不起作用。 对我来说最简单的解决方案是也模拟 window.getComputedStyle。 因此,第一部分是模拟触发错误的 getComputedStyle 函数。
global.window.getComputedStyle = jest.fn(x=>({}));
但是仍然需要createNodeMock来为输入节点提供一个空的样式对象。
TLDR;快照适用于此代码段
global.window.getComputedStyle = jest.fn(x=>({}));
const createNodeMock = (element) => ({
style: {},
});
const options={createNodeMock};
const tree = renderer
.create(form,options)
.toJSON();