如何解决模拟Aws-SDK中的玩笑范围错误:ReferenceError:初始化前无法访问'variable_name'
我正在尝试使用Jest测试框架来模拟aws-sdk。
这是我要在auth.js文件中测试的代码:
...
const AWS = require('aws-sdk');
AWS.config.update({ region: config.awsConfig.region });
...
const cognito = new AWS.CognitoIdentityServiceProvider();
await cognito.confirmSignUp(params).promise();
....
这是我的auth.spec.js文件中的测试代码:
const mockConfirmSignUp = jest.fn((params) => {
return {
promise() {
return Promise.resolve('mock response');
}
};
});
jest.mock('aws-sdk',() => {
return {
CognitoIdentityServiceProvider: jest.fn(() => ({
confirmSignUp: mockConfirmSignUp
})),config: {
update: jest.fn()
}
};
});
但是,当我测试代码时,会收到此错误:
ReferenceError: Cannot access 'mockConfirmSignUp' before initialization
我可以通过在mockConfirmSignUp
块内移动jest.mock
实现来使其工作,但是,我想在以后的情况下修改mockConfirmSignUp
的实现以返回{{1} }在jest中使用Promise.reject
实用程序来测试失败情况,并将此功能移到jest.mock块中将禁止我这样做。
我意识到这可能是“悬挂”问题,其中jest.mock悬挂在文件的顶部,但是下面的另一个类似测试用例对我来说却没有任何问题:
mockConfirmSignUp.mockImplementationOnce()
后一个代码与前一个代码有何不同?
解决方法
结果代码jest.mock
悬挂在相关的auth.js import
之上,两者都在const mockConfirmSignUp
变量声明之上。
在调用mockConfirmSignUp
时,第一个代码段访问CognitoIdentityServiceProvider
,这是在导入auth.js且在声明mockConfirmSignUp
之前发生的。第二个片段不这样做。
the manual描述了这种情况:
factory参数的局限性在于,由于对jest.mock()的调用被提升到文件的顶部,因此不可能先定义一个变量然后在工厂中使用它。以'mock'开头的变量例外。您有责任保证它们会按时初始化!
避免此问题的安全方法是将间谍从外部范围移动到模拟出口,以便对其进行访问以更改实现并声明它,这样可以在模块对象上对其进行访问:
import awssdk from 'awssdk';
jest.mock('aws-sdk',() => {
const mockConfirmSignUp = jest.fn(...);
return {
mockConfirmSignUp,CognitoIdentityServiceProvider: jest.fn(() => ({
confirmSignUp: mockConfirmSignUp
})),config: {
update: jest.fn()
}
};
});
...
expect(awssdk.mockConfirmSignUp).toBeCalledWith(...);
当起吊没有问题,但需要将可重用的模拟物从jest.mock
移至__mocks__
时,它也适用。
我可以通过在jest.mock块内移动mockConfirmSignUp实现来使其工作,但是,我想在随后的情况下修改mockConfirmSignUp的实现,以便在jest中使用mockConfirmSignUp.mockImplementationOnce()实用程序返回Promise.reject。 >
如果需要使用不同的依赖项对模块进行多次测试,则可以将auth.js和aws-sdk导入从顶级移至测试。这样,jest.mock
的吊装和mockConfirmSignUp
的安装就不会有问题。同样,重新导入要求使用jest.resetModules
或jest.isolateModules`。
我创建了这段代码,它运行良好(非常简单):
const mockedApiPost = jest.fn();
jest.mock('../../services/api',() => ({
post: () => {
mockedApiPost.call(mockedApiPost);
},}));
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。