我在Button.tsx中具有以下组件:
// Button.tsx
import * as React from 'react';
import { Button as ReactstrapButton } from 'reactstrap';
interface IHandlerParams<onClickArgsType> {
onClickParams?: onClickArgsType
}
export interface IButtonProps<onClickArgsType = {}> {
color?: string,
onClick?: (event: React.MouseEvent<any>, args?: onClickArgsType) => any,
handlersParams?: IHandlerParams<onClickArgsType>
}
interface IHandlers {
onClick: React.MouseEventHandler<any>
}
export class Button<onClickArgsType> extends React.Component<IButtonProps<onClickArgsType>> {
private handlers: IHandlers;
constructor(props: IButtonProps<onClickArgsType>) {
super(props);
this.handlers = {
onClick: (MouseEvent:React.MouseEvent<any>) => { if (this.props.onClick) {this.props.onClick( MouseEvent, this.props.handlersParams ? this.props.handlersParams.onClickParams : undefined) }}
}
}
render() {
return (
<ReactstrapButton
color={this.props.color}
onClick={this.handlers.onClick}>
{this.props.children}
</ReactstrapButton>
)
}
}
注意: :我正在使用该奇怪的“ handlers”对象来管理事件的回调,因此我在ReactstrapButton属性中没有直接的箭头功能,避免了每次创建一个新对象,从而防止重新渲染该组件。
以及Button.unit.test.tsx中的相应测试文件:
// Button.unit.test.tsx
import { mount, shallow } from "enzyme";
import * as React from "react";
import { Button, IButtonProps } from "./Button";
interface IOnClickParamsTest {
a: number,
b: number
}
describe('App component', () => {
it('renders without crashing', () => {
shallow(
<Button />
);
});
it('test the onClick method', () => {
const onClick = jest.fn((event: React.MouseEvent<IButtonProps<IOnClickParamsTest>>, params: IOnClickParamsTest) => params.a + params.b);
const onClickParams: IOnClickParamsTest = { a: 4, b: 5 };
const buttonComponent = mount(
<Button<IOnClickParamsTest>
onClick={onClick}
handlersParams={{ onClickParams }}
/>
);
buttonComponent.simulate("click");
expect(onClick).toBeCalled();
expect(onClick.mock.calls[0][1]).toBe(onClickParams);// The second argument of the first call to the function was onClickParams
// expect(onClick.mock.results[0].value).toBe(9);// The return value of the first call to the function was 9
});
});
测试按预期通过,但在最后注释的行中失败,并显示以下错误:
TypeError: Cannot read property '0' of undefined
该错误引用了onClick.mock.results属性。我已经调试了onClick.mock属性,结果当然不存在。但是,按照Jest中的this docs,其中应该存在一个results属性。
顺便说一句,我正在使用:
"react": "^16.4.0",
"react-dom": "^16.4.0",
"enzyme": "^3.3.0",
"enzyme-adapter-react-16": "^1.1.1",
"jest": "^23.1.0",
"jest-enzyme": "^6.0.2",
"ts-jest": "^22.4.6"
有什么想法吗?提前非常感谢您!
答案 0 :(得分:1)
Jest v23中提供了返回值。截至今天(2018年8月1日),已使用带有react-scripts-ts的create-react-app引导的应用程序正在使用Jest v22。 create-react-app将在不久的将来更新为使用Jest v23。
同时,可以使用Sinon fakes测试返回值。
在这种情况下,更新的测试如下:
// Button.unit.test.tsx
import { mount, shallow } from "enzyme";
import * as React from "react";
import * as sinon from 'sinon';
import { Button, IButtonProps } from "./Button";
interface IOnClickParamsTest {
a: number,
b: number
}
describe('App component', () => {
it('renders without crashing', () => {
shallow(
<Button />
);
});
it('test the onClick method', () => {
const onClick = sinon.fake((event: React.MouseEvent<IButtonProps<IOnClickParamsTest>>, params: IOnClickParamsTest) => params.a + params.b);
const onClickParams: IOnClickParamsTest = { a: 4, b: 5 };
const buttonComponent = mount(
<Button<IOnClickParamsTest>
onClick={onClick}
handlersParams={{ onClickParams }}
/>
);
buttonComponent.simulate("click");
expect(onClick.calledOnce).toBe(true);
expect(onClick.firstCall.args[1]).toBe(onClickParams);
expect(onClick.returnValues[0]).toBe(9);
});
});