我正在尝试测试componentDidMount
中的提取调用。尝试不同的解决方案,但总是死胡同。目前我有
组件
import React, { Component } from 'react';
import Seatmap from 'react-seatmap';
import '../../style/main.scss';
import seats from '../../seatData';
import Ticket from '../Ticket';
class Booking extends Component {
constructor(props){
super(props);
this.state = {
row: null,
number: null,
data: [],
selected: null,
isLoaded: false
}
this.addSeatCallback = this.addSeatCallback.bind(this);
this.removeSeatCallback = this.removeSeatCallback.bind(this);
}
controller = new AbortController();
async fetchData() {
await fetch(window.location.protocol + window.location.hostname,{
signal: this.controller.signal
})
.then(res => seats)
.then(
(result) => {
this.setState({
isLoaded: true,
data: this.formatSeatData(result)
});
},
(error) => {
this.setState({
isLoaded: true,
error
});
}
);
}
async componentDidMount(){
await this.fetchData();
}
componentWillUnmount() {
this.controller.abort();
}
getIndexFromLetter(letter) {
return letter.charCodeAt(0) - 65;
}
formatSeatData(seats){
const rows = [];
seats.seats.map( (seat,i) => {
const arr = seat.seatNumber.split(/([0-9]+)/).filter(Boolean);
seat.number = arr[0];
seat.isReserved = !seat.available;
const index = this.getIndexFromLetter(arr[1]);
if(typeof rows[index] === 'undefined') {
rows[index] = [];
}
rows[index].push(seat);
return true;
});
return rows;
}
addSeatCallback(row, number) {
const { data } = this.state;
const index = this.getIndexFromLetter(row);
this.setState({ row, number, selected: data[index][number-1] });
}
removeSeatCallback(row, number) {
this.setState({row: null, number: null, selected: null});
}
render() {
const { data, selected } = this.state;
if(Object.keys(data).length>0){
return (
<div className="container-fluid text-center">
<div className="" style={{float:'left', padding: '10px', marginTop:'10px'}}>
<Seatmap rows={data} maxReservableSeats={1} alpha addSeatCallback={this.addSeatCallback} removeSeatCallback={this.removeSeatCallback} />
</div>
<div className="" style={{float:'left', padding: '10px'}}>
<Ticket selected={selected} />
</div>
</div>
);
}
return null;
}
}
export default Booking;
测试
import React from 'react';
import ReactDOM from 'react-dom';
import Booking from '../../src/components/Booking';
import seats from '../../src/seatData';
import { shallow } from 'enzyme';
describe('Booking', () => {
it('renders without crashing', () => {
const div = document.createElement('div');
ReactDOM.render(<Booking />, div);
ReactDOM.unmountComponentAtNode(div);
});
let wrapper;
beforeEach(() => {
wrapper = shallow(<Booking />, { disableLifecycleMethods: true });
});
afterEach(() => {
wrapper.unmount();
});
it("must render a loading span before api call success", () => {
// expect(wrapper.find("span.loading").length).toBe(1);
});
it("componentDidMount", (done) => {
const spyDidMount = jest.spyOn(Booking.prototype,"componentDidMount");
fetch.mockImplementation(() => {
return Promise.resolve({
status: 200,
json: () => {
return Promise.resolve({
seats:{}
});
}
});
});
const didMount = wrapper.instance().componentDidMount();
expect(spyDidMount).toHaveBeenCalled();
didMount.then(() => {
wrapper.update();
expect(wrapper.find("div.seatmap_container"));
expect(wrapper.find("spans.loading").length).toBe(0);
spyDidMount.mockRestore();
fetch.mockClear();
done();
});
});
});
这是我的仓库https://github.com/shorif2000/elucidat-javascript-test
错误
PASS test/components/Booking.test.js
Booking
✓ renders without crashing (29ms)
✓ must render a loading span before api call success (1ms)
✓ componentDidMount (14ms)
console.error node_modules/react-dom/cjs/react-dom.development.js:545
Warning: Can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in the componentWillUnmount method.
in Booking
Test Suites: 1 passed, 1 total
Tests: 3 passed, 3 total
Snapshots: 0 total
Time: 2.145s
Ran all test suites matching /test\/components\/Booking.test.js/i.