【发布时间】:2021-10-31 06:20:57
【问题描述】:
在我的测试文件中,我正在安装一个组件,其中一个嵌套组件给我带来了麻烦。这是组件:
class CacheHandler extends React.Component {
constructor(props) {
super(props);
this.state = {
loading: true,
isLatestVersion: false,
refreshCacheAndReload: () => {
if (caches) {
caches.keys().then((names) => {
names.forEach((name) => {
caches.delete(name);
})
});
}
window.location.reload(true);
}
};
// ...some other code
}
render() {
const { loading, isLatestVersion, refreshCacheAndReload } = this.state;
return this.props.children({ loading, isLatestVersion, refreshCacheAndReload });
}
}
CacheHandler.propTypes = {
children: PropTypes.func.isRequired
};
export default CacheHandler;
我不知道如何正确地模拟构造函数的 refreshCacheAndReload 属性,这让我头发灰白。如果它在模拟中不做任何事情是完全可以的,但它应该在安装过程中被发现。目前,当我运行测试时,我得到了因为那部分 ReferenceError: EventSource is not defined
这是我在测试中尝试但失败的方法(错误:“CacheHandler”是只读的。):
const fakeCacheHandler = jest.fn(() => ({
constructor(props) {
//super(props);
this.state = {
loading: false,
isLatestVersion: false,
refreshCacheAndReload: () => { }
}},
render() {
const { loading, isLatestVersion, refreshCacheAndReload } = this.state;
return this.props.children({ loading, isLatestVersion, refreshCacheAndReload });
}
}))
CacheHandler = fakeCacheHandler;
我也尝试直接在测试中定义属性但没有成功:
Object.defineProperty(CacheHandler, 'CacheHandler', {
value: jest.fn().mockImplementation(query => ({
loading: false,
isLatestVersion: false,
refreshCacheAndReload: () => {}
}))
})
我还尝试像这样在测试中模拟整个模块:
jest.mock('../../components/utilities/CacheHandler', function() {
return jest.fn().mockImplementation(() => {
return {
refreshCacheAndReload: () => {},
render: () => {this.props.children({ loading:false, isLatestVersion:false, refreshCacheAndReload })},
}})
});
但仍然没有成功。
jest.spyOn 也失败(无法窥探 refreshCacheAndReload 属性,因为它不是函数;改为未定义)
const fakeHandler = new CacheHandler();
const methodSpy = jest.spyOn(fakeHandler, "refreshCacheAndReload");
methodSpy.mockImplementation(() => {
console.log('test!');
})
这就是测试本身现在的样子:
it('renders MembersList', async () => {
const Component = withMemory(AdminAppCore, ROUTE_ADMIN_MEMBERS);
const result = mount(
<MockProvider stores={{ memberStore, programStore }}>
<Component />
</MockProvider>
);
console.log(result.debug());
await waitForState(result, state => state.loading === false);
expect(result.find(MembersList).length).toBe(1);
result.unmount();
});
我试图像这样在测试中模拟子元素的构造函数,但是如果失败(TypeError:this.props.children is not a function):
it('renders MembersList', async () => {
const Component = withMemory(AdminAppCore, ROUTE_ADMIN_MEMBERS);
const mockrefreshCacheAndReload = jest.fn(() => ({}));
const component = shallow(<CacheHandler/>);
component.setState({refreshCacheAndReload: mockrefreshCacheAndReload});
const result = mount(
<MockProvider stores={{ memberStore, programStore }}>
<Component />
</MockProvider>
);
console.log(result.debug());
await waitForState(result, state => state.loading === false);
expect(result.find(MembersList).length).toBe(1);
result.unmount();
});
所以我正在安装 AdminAppCore,而 AdminAppCore 内部是导致麻烦的嵌套组件。
谁能解释我如何模拟嵌套组件构造函数中的 refreshCacheAndReload 状态?
【问题讨论】:
-
你试过使用 jest spy 吗?它类似于 const methodSpy = jest.spy(classInstance, "methodNameInString"); methodSpy.mockImplementation..
-
是的,我做到了,但我收到错误 TypeError: jest.spy is not a function :( 我这样尝试过: const methodSpy = jest.spy(CacheHandler, "refreshCacheAndReload"); methodSpy. mockImplementation(() => { //***** 实现**** })
-
对不起,该函数被称为 jest.spyOn 而不是 jest.spy 此外,您可能需要一个 CacheHandler 的实例而不是类本身才能使其工作。
-
我可以在测试本身内创建实例吗?我试过了,但没有用。我总是收到错误无法监视 refreshCacheAndReload 属性,因为它不是函数;给定的未定义
-
好的,所以问题是我们忽略了方法是状态的一部分这一事实。为了测试这个组件,你需要使用 jest/enzyme 加载这个组件,然后为 refreshCacheAndReload 创建一个模拟函数,然后将它附加到状态。有意义吗?
标签: javascript unit-testing jestjs enzyme