在开玩笑中模拟 react ref 的当前值以进行浅层测试
Mocking current value of react ref in jest for shallow test
我正在尝试模拟 this.ref.current.value
作为我的 React 组件中功能测试的一部分。
当前 current
为空,因为我正在对我的组件进行浅安装。我正在尝试找到一种方法来为我的 ref 模拟 current.value
returns 的内容,以便我可以测试函数的另一部分,refs 的值实际上对这个测试并不重要。
实际函数:
copyDefinitionTarget = selectedInput => () => {
// get and select the input value
const copyText = this[`${selectedInput}`].current.value;
// copy to clipboard
navigator.clipboard.writeText(copyText);
};
测试代码:
it('calls navigator.clipboard appropriately to copy the text in copyDefinitionTarget', () => {
component = shallow(<Alert {...props} />);
component
.dive()
.find('Item')
.dive()
.find('Button')
.simulate('click');
expect(navigator.clipboard.writeText).toHaveBeenCalled();
});
测试失败:
TypeError: Cannot read property 'value' of null
50 | // get and select the input value
> 51 | const copyText = this[`${selectedInput}`].current.value;
有什么办法吗?我关心的是测试 navigator.clipboard 被调用而不是它被调用的内容。
正在更新,因为我已将代码更改为使用 this.ref
而不是 stringRefName
实际函数:
copyDefinitionTarget = selectedInput => () => {
// get and select the input value
const copyText = selectedInput.current.value;
// copy to clipboard
navigator.clipboard.writeText(copyText);
};
测试代码:
it('calls navigator.clipboard appropriately to copy the text in copyDefinitionTarget', () => {
component = shallow(<Alert {...props} />);
instance = component.instance();
// we are clicking on the first Alert Item
// so mock that ref specifically
instance.firstNameRef = {
current: {
value: 'stuff'
}
};
component
.dive()
.find('Item')
.dive()
.find('Button')
.simulate('click');
expect(navigator.clipboard.writeText).toHaveBeenCalled();
});
函数调用:
<Item
inputRef={this.firstNameRef}
inputValue={`${realmName}`}
copyDefinitionTarget={this.copyDefinitionTarget(this.firstNameRef)}
/>
您可以继续这样做:
const component = shallow(<Alert {...props} />);
const selectedInput = 'ref';
component.instance()[selectedInput] = {
current: {
value: 'stuff'
}
}
navigator.clipboard = {writeText: jest.fn()}
component
.dive()
.find('Item')
.dive()
.find('Button')
.simulate('click');
expect(navigator.clipboard.writeText).toHaveBeenCalled();
注意:我不确定selectedInput
应该是什么样的字符串,您可以根据您的实际组件代码传递任何合适的字符串。
由于 ref 作为实例 属性 在组件上存在,您可以传递任何您想要的对象,只要它看起来像 current.value
,然后你可以用mock替换copy函数,模拟点击然后看看是否调用了writeText
发布另一种方法,如果您传递的是实际引用而不是字符串,则可以采用该方法。我将 ref 中的值提取到它自己的函数中,并在我的测试中模拟了它
实际代码:
// get the value from ref
getRefValue = ref => ref.current.value;
// copy value
copyDefinitionTarget = selectedInput => () => {
// get and select the input value
const copyText = this.getRefValue(selectedInput);
// copy to clipboard
navigator.clipboard.writeText(copyText);
};
测试代码:
it('calls navigator.clipboard appropriately to copy the text in copyDefinitionTarget', () => {
component = shallow(<MetadataAlert {...props} />);
instance = component.instance();
jest.spyOn(instance, 'getRefValue').mockImplementationOnce(() => '');
component
.dive()
.find('Item')
.dive()
.find('Button')
.simulate('click');
expect(navigator.clipboard.writeText).toHaveBeenCalled();
});
我正在尝试模拟 this.ref.current.value
作为我的 React 组件中功能测试的一部分。
当前 current
为空,因为我正在对我的组件进行浅安装。我正在尝试找到一种方法来为我的 ref 模拟 current.value
returns 的内容,以便我可以测试函数的另一部分,refs 的值实际上对这个测试并不重要。
实际函数:
copyDefinitionTarget = selectedInput => () => {
// get and select the input value
const copyText = this[`${selectedInput}`].current.value;
// copy to clipboard
navigator.clipboard.writeText(copyText);
};
测试代码:
it('calls navigator.clipboard appropriately to copy the text in copyDefinitionTarget', () => {
component = shallow(<Alert {...props} />);
component
.dive()
.find('Item')
.dive()
.find('Button')
.simulate('click');
expect(navigator.clipboard.writeText).toHaveBeenCalled();
});
测试失败:
TypeError: Cannot read property 'value' of null
50 | // get and select the input value
> 51 | const copyText = this[`${selectedInput}`].current.value;
有什么办法吗?我关心的是测试 navigator.clipboard 被调用而不是它被调用的内容。
正在更新,因为我已将代码更改为使用 this.ref
而不是 stringRefName
实际函数:
copyDefinitionTarget = selectedInput => () => {
// get and select the input value
const copyText = selectedInput.current.value;
// copy to clipboard
navigator.clipboard.writeText(copyText);
};
测试代码:
it('calls navigator.clipboard appropriately to copy the text in copyDefinitionTarget', () => {
component = shallow(<Alert {...props} />);
instance = component.instance();
// we are clicking on the first Alert Item
// so mock that ref specifically
instance.firstNameRef = {
current: {
value: 'stuff'
}
};
component
.dive()
.find('Item')
.dive()
.find('Button')
.simulate('click');
expect(navigator.clipboard.writeText).toHaveBeenCalled();
});
函数调用:
<Item
inputRef={this.firstNameRef}
inputValue={`${realmName}`}
copyDefinitionTarget={this.copyDefinitionTarget(this.firstNameRef)}
/>
您可以继续这样做:
const component = shallow(<Alert {...props} />);
const selectedInput = 'ref';
component.instance()[selectedInput] = {
current: {
value: 'stuff'
}
}
navigator.clipboard = {writeText: jest.fn()}
component
.dive()
.find('Item')
.dive()
.find('Button')
.simulate('click');
expect(navigator.clipboard.writeText).toHaveBeenCalled();
注意:我不确定selectedInput
应该是什么样的字符串,您可以根据您的实际组件代码传递任何合适的字符串。
由于 ref 作为实例 属性 在组件上存在,您可以传递任何您想要的对象,只要它看起来像 current.value
,然后你可以用mock替换copy函数,模拟点击然后看看是否调用了writeText
发布另一种方法,如果您传递的是实际引用而不是字符串,则可以采用该方法。我将 ref 中的值提取到它自己的函数中,并在我的测试中模拟了它
实际代码:
// get the value from ref
getRefValue = ref => ref.current.value;
// copy value
copyDefinitionTarget = selectedInput => () => {
// get and select the input value
const copyText = this.getRefValue(selectedInput);
// copy to clipboard
navigator.clipboard.writeText(copyText);
};
测试代码:
it('calls navigator.clipboard appropriately to copy the text in copyDefinitionTarget', () => {
component = shallow(<MetadataAlert {...props} />);
instance = component.instance();
jest.spyOn(instance, 'getRefValue').mockImplementationOnce(() => '');
component
.dive()
.find('Item')
.dive()
.find('Button')
.simulate('click');
expect(navigator.clipboard.writeText).toHaveBeenCalled();
});