gpt4 book ai didi

node.js - 为什么我的 Sinon spy 函数在 promise then 子句中调用时不起作用?

转载 作者:搜寻专家 更新时间:2023-10-31 23:52:29 25 4
gpt4 key购买 nike

我正在为基于 Promise 的函数编写测试。具体来说,它是一个 React 组件,我正在测试以确保正确调用 onChange 处理程序。

我的组件如下所示:

class TextInput extends React.Component {
constructor(props) {
super(props);

this.state = {
value: props.value || '',
};

this.onChange = this.onChange.bind(this);
}

updateState(values) {
return new Promise(
(resolve) => {
this.setState(values, () => { resolve(this.state); });
}
);
}

onChange(event) {
this.updateState({ value: event.target.value })
// then fire the onChange handler (if necessary)
//
.then((state) => {
if (this.props.onChange) {
// console.log(this.props.onChange) shows that this IS a
// Sinon spy function
this.props.onChange(state.value);
}
})

.catch((err) => { console.log('-----------', err); });
}

render() {
// render the component (omitted to keep this short)
}
}

我的测试是这样的:

import React from 'react';
import { mount } from 'enzyme';
import chai from 'chai';
import sinon from 'sinon';
import TextInput from '../../../../client/modules/components/TextInput';

const expect = chai.expect;

describe('TextInput component editing', () => {

it('calls the onChange handler', () => {

const onchange = sinon.spy();

const value = '';
const editedValue = 'something';

const component = mount(<TextInput value={value} onChange={onchange} />);

// change the value
//
component.find('input').simulate('change', {
target: { value: editedValue }
});

expect(component.find('input').prop('value')).to.equal(editedValue);

expect(onchange.calledOnce).to.equal(true);
expect(onchange.calledWith(editedValue)).to.equal(true);
});
});

最后两次 expect 调用测试失败。

如果我用普通的旧函数替换 sinon spy,则调用该函数。例如,

// instead of this...
// const onchange = sinon.spy();

// do this...
const onchange = (value) => { console.log(`VALUE = ${value}`); };

如果我直接使用 setState 方法的回调,它会起作用。例如,

// instead of...
// this.updateState(values).then(...)

// do this...
this.setState(values, () => {
// call the onChange handler...
});

我可以这样做,但我想避免它,因为我要为这个组件添加更多功能,我不想陷入 pyramid of doom 的困境。 .

起初我认为这可能与 updateState 方法范围内的 this 或该方法中的回调函数之一有关,但是在整个过程中添加 console.log 语句表明 this 在所有适当的位置引用了 TextInput 的实例。

添加 console.log 语句以在 onChange 处理程序被触发之前转储显示 this.props.onChange 在事实上,诗乃的 spy 。

我查看了其他包,例如 sinon-as-promised ,但我认为该包并没有真正解决我正在尝试做的事情——我只是想确保在 promise then 子句中调用我的回调。 sinon-as-promised 是一个用来 stub 整个 promise 的包。

我可能忽略了一些直截了当的东西,但不管它是什么,我都没有看到。

最佳答案

在执行对状态的异步调用之前,您的同步测试似乎已经完成。我不会评论您是否应该同时设置状态和调用更改方法以及何时。但我认为您当前的简单答案是通过传入 done 参数来使用异步测试。 (很明显,那时你甚至不需要 spy ,但我把它留在里面只是为了表明不是 spy 本身不起作用:

describe('TextInput component editing', () => {
it('calls the onChange handler', done => {
const fakeOnChange = stuff => {
expect(spyOnChange.calledOnce).to.equal(true);
expect(editedValue).to.equal(stuff);
expect(component.find('input').prop('value')).to.equal(editedValue);
done();
}

const spyOnChange = sinon.spy(fakeOnChange);

const value = '';
const editedValue = 'something';

const component = mount(<TextInput value={value} onChange={spyOnChange} />);

component.find('input').simulate('change', {
target: { value: editedValue }
});

});
});

关于node.js - 为什么我的 Sinon spy 函数在 promise then 子句中调用时不起作用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38751247/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com