我正在将React组件库从JS转换为TS,并且jest.mock()遇到问题。
之前:
"react": "^15.6.1"
"jest": "20.0.4"
"enzyme": "^2.9.1"
CustomDate.js
...
import DatePicker from 'react-datepicker';
...
export default class CustomDate extends React.Component {
...
render() {
return (
<div onChange={this.handleDivChange}>
<DatePicker
...
/>
</div>
);
}
}
CustomDate.test.js
...
import CustomDate from '../component/CustomDate';
import DatePicker from 'react-datepicker';
jest.mock('react-datepicker', () => {
let React = require('react');
return class DatePicker extends React.Component {
render() {
return (
<div id='DatePicker'></div>
);
}
};
});
...
beforeEach(function () {
customDate = mount(<CustomDate {...testProps}/>);
});
...
it('renders a DatePicker component', () => {
console.log(customDate.find('div').at(0).html()); -> outputs <div><div id='DatePicker'></div></div>, not the react datepicker
console.log(customDate.find('div').at(1).html()); -> outputs <div id='DatePicker'></div>, not the react datepicker
expect(customDate.find(DatePicker).length).toBe(1);
});
之后:
"react": "^16.4.2"
"typescript": "^2.9.2"
"jest": "^23.5.0"
"ts-jest": "^23.1.4"
"enzyme": "^3.5.0"
"enzyme-adapter-react-16": "^1.3.0"
CustomDate.tsx
...
import DatePicker from 'react-datepicker';
...
export default class CustomDate extends Component<CustomDateProps, CustomDateState> {
...
render() {
return (
<div onChange={this.handleDivChange}>
<DatePicker
...
/>
</div>
);
}
}
CustomDate.test.tsx
...
import CustomDate from '../component/CustomDate';
import DatePicker from 'react-datepicker';
jest.mock('react-datepicker', () => {
let React = require('react');
return class DatePicker extends React.Component {
render() {
return (
<div id='DatePicker'></div>
);
}
};
});
...
beforeEach(function () {
customDate = mount(<CustomDate {...testProps}/>);
});
...
it('renders a DatePicker component', () => {
expect(customDate.find(DatePicker).length).toBe(1);
});
运行测试时,我收到以下消息:
CustomDate.test.tsx: babel-plugin-jest-hoist: The module factory of `jest.mock()` is not allowed to reference any out-of-scope variable
s.
Invalid variable access: __extends
...
Note: This is a precaution to guard against uninitialized mock variables. If it is ensured that the mock is required lazily, variable names prefixed with `mock` are permitted.
我花了一天时间尝试不同的事情。有些人摆脱了错误,但并没有真正嘲笑DatePicker。我要放松一下。
任何帮助将不胜感激。
更新
已编译的测试文件:
"use strict";
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
return extendStatics(d, b);
}
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
exports.__esModule = true;
var React = require("react");
var mockDatePicker = /** @class */ (function (_super) {
__extends(mockDatePicker, _super);
function mockDatePicker() {
return _super !== null && _super.apply(this, arguments) || this;
}
mockDatePicker.prototype.render = function () {
return React.createElement("div", { id: "DatePicker1" });
};
return mockDatePicker;
}(React.Component));
jest.mock('react-datepicker', function () { return mockDatePicker; });
答案 0 :(得分:0)
当您使用带有某些代码的转译器(例如TypeScript)时,通常能够查看实际生成的代码,以更好地理解为什么会看到此类错误。例如,如果我使用您的存根DatePicker类并用tsc
进行编译,则会得到以下内容:
"use strict";
var __extends = (this && this.__extends) || (function () {
var extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
var React = require("react");
var DatePicker = /** @class */ (function (_super) {
__extends(DatePicker, _super);
function DatePicker() {
return _super !== null && _super.apply(this, arguments) || this;
}
DatePicker.prototype.render = function () {
return (React.createElement("div", { id: 'DatePicker' }));
};
return DatePicker;
}(React.Component));
在这里,您可以看到__extends是TypeScript定义的函数,并放置在“ __extends”变量中。这已经超出了范围(请参阅您所发布的错误),因为jest将所有对jest.mock的调用移至文件顶部(在babel的帮助下)。
一种解决方案是在要设置模拟的闭包之外定义模拟类。例如:
import * as React from "react";
class MockDatePicker extends React.Component {
// ...
}
jest.mock("react-datepicker", () => MockDatePicker);
答案 1 :(得分:0)
我发现了另一种模拟react-datepicker的方法:
CustomDate.test.tsx
jest.mock('react-datepicker',
() => require.requireActual('../test/mocks/DatePickerMock').default());
DatePickerMock.tsx
import * as React from 'react';
export class DatePicker extends React.Component {
render() {
return <div id="DatePicker"/>;
}
}
export default DatePicker;