javascript - 一个接受第三方回调的方法的笑话模拟实现
问题描述
我正在使用 Nest + Cognito 对应用程序上的用户进行身份验证,我的身份验证服务中有一个方法,我正在尝试测试/模拟,它是:
async cognitoRegister(userPool: CognitoUserPool, {
name,
password,
email
}: AuthRegisterInput): Promise < ISignUpResult > {
return new Promise((resolve, reject) => {
return userPool.signUp(
name,
password,
[new CognitoUserAttribute({
Name: 'email',
Value: email
})],
null,
(err, result) => {
if (!result) {
reject(err);
} else {
resolve(result);
}
},
);
});
}
这里的signUp函数是一个来自第三方 CognitoUserPool 的方法,我设法使用 package.json 中的模块名称映射器对其进行了模拟,这里是:
function CognitoUserPool(data) {
const { UserPoolId, ClientId } = data;
this.userPoolId = UserPoolId;
this.clientId = ClientId;
this.getCurrentUser = jest.fn().mockReturnValue("cognitouserpool");
// This method
this.signUp = jest.fn().mockReturnValue(true);
}
module.exports = CognitoUserPool;
并且是实施:
module.exports = {
CognitoUserPool: jest.fn().mockImplementation(require("./CognitoUserPool")),
};
由于 signUp 方法接受一个回调,它负责给我一个结果/拒绝值,我应该以某种方式模拟它,否则 Jest 给我一个超时错误,因为实现返回一个保持在挂起状态的 Promise。
基本上我正在尝试模拟这种功能:
const foo = (arg1, cb) => {
...do something...
}
const bar = (arg1, arg2...) => {
return new Promise((resolve, reject) => {
return foo(arg1, (err, result) => {
if (!result) {
reject(err)
} else {
resolve(result)
}
})
})
}
这是我在测试中尝试做的事情:
it("should register a cognito user", async () => {
const mockedCongitoUserPool = new CognitoUserPool({
UserPoolId: authConfig.userPoolId,
ClientId: authConfig.clientId,
});
const result = await service.cognitoRegister(mockedCongitoUserPool, {
...mockedUser,
});
console.log(result);
});
我也有一个 git 可能会有所帮助:
感谢这里的任何帮助<3,要求任何进一步的解释我真的需要一些帮助。
解决方案
要获得静态解析,您的模拟模块应声明如下实现,而不仅仅是返回值:
this.signUp = jest.fn().mockImplementation((name, pwd, attlist, something, cb) => {
process.nextTick(cb(null, 'signedup!'))
});
这里process.nextTick
只是模拟异步,但cb(null, 'some result')
如果您不在乎,也可以调用。
如果您想动态控制回调解析,您可以根据您的场景覆盖默认的模拟实现:
let cup: CognitoUserPool;
beforeAll(() => { // or maybe beforeEach, depends on what the mock keeps/does
cup = new CognitoUserPool({ userPoolId: 'fakeUserPoolId', ClientId: 'fakeClientId' });
});
it('should resolve', async () => {
const expected = { any: 'thing' };
cup.signUp.mockImplementation((a, b, c, d, cb) => cb(null, expected));
await expect(service.cognitoRegister(cup, mockedUser)).resolves.toBe(expected);
});
it('should fail', async () => {
const expected = new Error('boom!');
cup.signUp.mockImplementation((a, b, c, d, cb) => cb(expected));
await expect(service.cognitoRegister(cup, mockedUser)).rejects.toThrow(expected);
});
推荐阅读
- docker - 'stderr: remove /etc/passwd' 在构建 Docker 容器时
- reactjs - React intl 模板字符串抛出一个错过的 id 警告
- tfs - TFS 2018 和 AppCenter 测试
- yaml - Yaml : yaml 文件中的格式错误。预期的 '
',但发现' - single-sign-on - Apereo CAS分两步加载用户属性并存储起来进行属性发布
- reactjs - 我可以在这个常量中传递一个列表查询吗?
- python - 根据 leetcode 的“列表索引超出范围”。但在 IDLE 中工作
- android - 片段如何在内部接收应用程序的上下文(内部工作)
- asp.net-mvc - 模型字符串中的 href 导致 mvc 抛出 Failed to map the path 错误
- intellij-idea - 无法更改日期样式 intellij IDE