我有一个HOC函数,该函数接收React组件并返回带有两个新方法属性(handleBack
和moveitOnTop
)的react组件,如下所示:
import React, { Component } from "react";
import classNames from "classnames";
export default WrappedComponent => {
return class extends Component {
constructor(props) {
super(props);
this.moveitOnTop = this.moveitOnTop.bind(this);
this.handleBack = this.handleBack.bind(this);
this.state = {
isSearchActive: false
};
}
moveitOnTop(flag) {
this.setState({ isSearchActive: flag });
window.scrollTo(0, -100);
}
handleBack() {
this.setState({ isSearchActive: false });
if (document.body.classList.contains("lock-position")) {
document.body.classList.remove("lock-position");
}
}
render() {
const props = {
...this.props,
isSearchActive: this.state.isSearchActive,
moveitOnTop: this.moveitOnTop,
goBack: this.handleBack
};
const classes = classNames({ "c-ftsOnTop": this.state.isSearchActive });
return (
<div className={classes}>
<WrappedComponent {...props} />
</div>
);
}
};
};
组件:
//import fireAnalytics
import { fireAnalytics } from "@modules/js-utils/lib";
class MyComponent extender Component{
constructor(){
super(props);
this.handleClick = this.handleClick.bind(this);
}
handleClick(e) {
// calling analytics function by passing vals
fireAnalytics({
event: "GAEvent",
category: "",
action: `Clicked on the ${e.target.id} input`,
label: "Click"
});
// I CALL THE HOC PROPERTY
this.props.moveitOnTop(true);
// I CALL THE HOC PROPERTY
this.props.handleBack();
}
render(){
return(
<div className="emailBlock">
<input type="text" onClick={handleClick} />
<Button className="submit">Submit</Button>
</div>
)
}
}
// export HOC component
export default hoc(MyComponent);
// export just MyComponent
export {MyComponent};
我要测试HOC:
.c-ftsOnTop
是否存在onClick
和`this.props.moveitOnTop'的this.props.handleBack
函数emailBlock
是否存在。我尝试过但失败的测试:
import { mount, shallow } from 'enzyme';
import sinon from 'sinon';
import React from 'react';
import { expect } from 'chai';
import hoc from '....';
import {MyComponent} from '...';
import MyComponent from '....';
it('renders component', () => {
const props = {}
const HocComponent = hoc(MyComponent);
const wrapper = mount(
<HocComponent {...props} />
);
console.log('wrapper:', wrapper);
expect(wrapper.find('.c-ftsOnTop')).to.have.lengthOf(1);
expect(wrapper.hasClass('c-fts-input-container')).toEqual(true);
})
错误
AssertionError: expected {} to have a length of 1 but got 0
console.log:wrapper: ReactWrapper {}
有人可以帮助我呈现HOC吗?
答案 0 :(得分:0)
这是一个有效的测试:
import { mount } from 'enzyme';
import React from 'react';
import WrappedMyComponent from './MyComponent';
it('renders component', () => {
const props = {}
const moveitOnTopSpy = jest.spyOn(WrappedMyComponent.prototype, 'moveitOnTop');
const handleBackSpy = jest.spyOn(WrappedMyComponent.prototype, 'handleBack');
const wrapper = mount(
<WrappedMyComponent {...props} />
);
// 1. I need to check that class .c-ftsOnTop exists
wrapper.setState({ isSearchActive: true }); // <= set isSearchActive to true so .c-ftsOnTop is added
expect(wrapper.find('.c-ftsOnTop')).toHaveLength(1); // Success!
// 2. I need to check onClick function that calls this.props.handleBack & `this.props.moveitOnTop'
window.scrollTo = jest.fn(); // mock window.scrollTo
wrapper.find('input').props().onClick();
expect(moveitOnTopSpy).toHaveBeenCalled(); // Success!
expect(window.scrollTo).toHaveBeenCalledWith(0, -100); // Success!
expect(handleBackSpy).toHaveBeenCalled(); // Success!
// 3. I need to check if className emailBlock exists
expect(wrapper.find('.emailBlock')).toHaveLength(1); // Success!
})
详细信息
.c-ftsOnTop
仅在isSearchActive
为true
时添加,因此只需设置组件的状态即可添加类。
如果您在moveitOnTop
和handleBack
的原型方法上创建间谍,那么当hoc
通过将其实例方法绑定到构造函数中的this
来创建其实例方法时,实例方法将绑定到您的间谍。
window.scrollTo
默认在jsdom
中将错误记录到控制台,因此您可以模拟该错误以避免该错误消息并验证是否已使用期望的参数调用了该错误消息。
请注意,以上测试要求在MyComponent
中修复以下拼写错误:
extender
应该是extends
constructor
应该接受一个props
参数onClick
应该绑定到this.handleClick
而不是handleClick
handleClick
应该呼叫this.props.goBack()
而不是this.props.handleBack()
(我猜MyComponent
只是作为实际组件的一个例子而已)