Javascript Jest快照测试TypeError:对不可重写实例进行破坏结构的尝试无效
我的react代码库中有一个组件,我试图为它创建一些快照测试,但不幸的是,出现了一些奇怪的错误,jest暗示我正在对不可迭代的实例和日志进行一些解构,显示出一些东西,无论我多么努力地思考它,它都能完美地工作,但我不知道下图所示的这段代码有什么问题: 另外请注意,我在我的组件中为Javascript Jest快照测试TypeError:对不可重写实例进行破坏结构的尝试无效,javascript,reactjs,testing,jestjs,snapshot,Javascript,Reactjs,Testing,Jestjs,Snapshot,我的react代码库中有一个组件,我试图为它创建一些快照测试,但不幸的是,出现了一些奇怪的错误,jest暗示我正在对不可迭代的实例和日志进行一些解构,显示出一些东西,无论我多么努力地思考它,它都能完美地工作,但我不知道下图所示的这段代码有什么问题: 另外请注意,我在我的组件中为formik进行了模拟,如下所示: jest.mock('formik', () => ({ useField: jest.fn(), useFormikContext: jest.fn(), }));
formik
进行了模拟,如下所示:
jest.mock('formik', () => ({
useField: jest.fn(),
useFormikContext: jest.fn(),
}));
和这个话题相关的每一个问题要么不是开玩笑的,要么答案不起作用,甚至不被接受
任何帮助都将得到感谢
这是我的测试文件:
import React from 'react';
import renderer from 'react-test-renderer';
import MyComponent from '../MyComponent';
jest.mock('../MyComponentManager');
jest.mock('formik', () => ({
useField: jest.fn(),
useFormikContext: jest.fn().mockReturnValue({ isValidating: false, setFieldValue: () => {} }),
}));
describe('MyComponent', () => {
test('should render component properly', () => {
const component = renderer.create(<MyComponent />);
const tree = component.toJSON();
expect(tree).toMatchSnapshot();
});
});
从“React”导入React;
从“反应测试渲染器”导入渲染器;
从“../MyComponent”导入MyComponent;
jest.mock('../MyComponentManager');
开玩笑的模仿('formik',()=>({
useField:jest.fn(),
useFormikContext:jest.fn().mockReturnValue({isValidating:false,setFieldValue:()=>{}),
}));
描述('MyComponent',()=>{
测试('应正确呈现组件',()=>{
const component=renderer.create();
const tree=component.toJSON();
expect(tree.toMatchSnapshot();
});
});
下面是正在测试的组件的次要版本:
const MyComponent = () => {
<SomeWrapperComponent>
...some jsx
<NumberField {...props} />
</SomeWrapperComponent>
}
常量MyComponent=()=>{
…一些jsx
}
错误发生在
组件的一侧,我相信您的问题在于设置useformiccontext:jest.fn()
<默认情况下,code>jest.fn()返回一个函数,该函数返回中提到的undefined
。这样,您就可以尝试解构未定义的
您需要模拟useformiccontext
函数的返回值:
jest.mock('formik', () => ({
useField: jest.fn(),
useFormikContext: jest.fn().mockReturnValue({ isValidating: false, setFieldValue: () => {} }),
}));
如果没有帮助,请添加完整的和简单的可运行的示例,这样我可以更深入地了解。(即测试文件和代码文件)
编辑
我看到您只模拟了formik
模块的useField
useFormikContext
函数,尽管您可能使用了formik
模块中的更多功能,如formik
标记等,但它们现在被覆盖了
jest.mock
覆盖整个模块,不适合您的用例,因为您只想模拟useField
&useformiccontext
我喜欢使用jest.spyOn
,它只能用来模拟模块的特定功能。请参见关于jest.spyOn的
下面是一个完整的工作小示例,它是在开玩笑时模仿formik的react测试
example.js-正在测试的react组件
example.spec.js-简单jest测试
example.js:
import React from 'react';
import { useFormikContext, Formik, Form, Field } from 'formik';
export const OtherComponent = () => {
// Grab values and submitForm from context
const { isValidating, setFieldValue } = useFormikContext();
return (
<div>
<div>{isValidating ? 'validating...' : 'validated!'}</div>
<button type="submit" disabled={isValidating}>
submit
</button>
<button
type="button"
disabled={isValidating}
onClick={() => {
setFieldValue('token', '123456');
}}
>
return to default
</button>
</div>
);
};
export const ExmpleComponent = () => {
return (
<div>
<h1>Example</h1>
<Formik
initialValues={{ token: '' }}
validate={(values) => {
return new Promise((resolve, _reject) => setTimeout(resolve, 3000)).then(() => {
// wait 3 seconds
const errors = {}; // no errors
return errors;
});
}}
onSubmit={(_values, _actions) => {
console.log('submitted!');
}}
>
<Form>
<Field name="token" type="tel" />
<OtherComponent />
</Form>
</Formik>
</div>
);
};
从“React”导入React;
从'Formik'导入{useFormikContext,Formik,Form,Field};
导出常量其他组件=()=>{
//从上下文中获取值并提交表单
常量{isValidating,setFieldValue}=UseFormicContext();
返回(
{正在验证?'validating…':'validated!'
提交
{
setFieldValue('token','123456');
}}
>
恢复默认
);
};
导出常量ExampleComponent=()=>{
返回(
例子
{
返回新承诺((resolve,_reject)=>setTimeout(resolve,3000))。然后(()=>{
//等3秒钟
常量错误={};//无错误
返回错误;
});
}}
onSubmit={(\u值,\u操作)=>{
console.log('submitted!');
}}
>
);
};
example.spec.js:
import React from 'react';
import renderer from 'react-test-renderer';
import * as formik from 'formik';
import { ExmpleComponent } from '../src/example.js';
// jest.mock('formik', () => ({
// useField: jest.fn(),
// useFormikContext: jest.fn().mockReturnValue({ isValidating: false, setFieldValue: () => {} }),
// }));
describe('MyComponent', () => {
test('should render component properly', () => {
const useFieldSpy = jest.spyOn(formik, 'useField');
const useFormikContextSpy = jest.spyOn(formik, 'useFormikContext');
useFieldSpy.mockReturnValue(undefined);
useFormikContextSpy.mockReturnValue({ isValidating: true, setFieldValue: () => {} });
const component = renderer.create(<ExmpleComponent />);
const tree = component.toJSON();
expect(tree.children[1].children[1].children[0].children[0]).toBe('validating...');
useFieldSpy.mockRestore();
useFormikContextSpy.mockRestore();
});
});
从“React”导入React;
从“反应测试渲染器”导入渲染器;
从“formik”导入*作为formik;
从“../src/example.js”导入{examplecomponent};
//开玩笑的模仿('formik',()=>({
//useField:jest.fn(),
//useFormikContext:jest.fn().mockReturnValue({isValidating:false,setFieldValue:()=>{}),
// }));
描述('MyComponent',()=>{
测试('应正确呈现组件',()=>{
const useFieldSpy=jest.spyOn(formik,'useField');
const useFormikContextSpy=jest.spyOn(formik,“useFormikContext”);
useFieldSpy.mockReturnValue(未定义);
UseFormicContextSpy.mockReturnValue({isValidating:true,setFieldValue:()=>{});
const component=renderer.create();
const tree=component.toJSON();
预期(tree.children[1]。children[1]。children[0]。children[0]).toBe('validating…');
useFieldSpy.mockRestore();
useformicContextSpy.mockRestore();
});
});
如果仍然不起作用,请添加完整和简单示例,我可以运行自己测试,查看代码中的错误。您添加了测试文件的完整示例,但没有添加您正在测试的代码。我在我的代码示例jest.mock('formik',()=>({useField:jest.fn(),useformicContext:()=>jest.fn().mockReturnValue({isValidating:false,setFIeldValue:()=>{}),})代码>它不起作用您需要将useformiccontext
设置为justjest.fn().mockReturnValue({isValidating:false,setFIeldValue:()=>{}}})
,而不是返回jest.fn()
的函数。如果这仍然不起作用,请同时添加完整的代码示例(正在测试),并删除不必要的代码以使其变得简单。我编辑了我的答案来展示我在这里写的东西。我这样做了,但没有起作用,我真的很感谢你的帮助,我更新了代码,我在
中使用了一些组件,它称为
组件,我在该组件中使用UseFormicContext
逻辑。我已经试过并做了一个例子。请参阅我的编辑。