如何模拟回调函数以在 Angular 8 中使用 jasmine 测试 promise
How to mock a callback function to test a promise in with jasmine in Angular 8
我有一个 returns 承诺并调用另一个函数的函数,该函数将回调作为参数,但我无法弄清楚如何模拟回调函数或调用它的函数。
我要模拟的函数 "listenOnAMessageWithCallBack" 来自我正在注入的服务,我还想模拟它调用的回调函数。
我的实现:
async getUsername(): Promise<string> {
return await new Promise<string>((resolve, reject) => {
try {
this.electronController.sendMessage('userName');
let cb = (event, username) =>{
this.username = username;
let user = this.stripDomain(this.username);
resolve(user);
};
this.electronController.listenOnAMessageWithCallBack('catchUser', cb);
} catch (err) {
reject(err);
}
})
}
我的测试如下:
it('testing function with callback', async() => {
const stripDomain = spyOn(service, 'stripDomain').and.callFake(()=>{
service.username = service.username.split('\').reverse()[0];
return service.username;
});
let cb = (event, username)=>{Promise.resolve('username')}
spyOn(electronController, 'listenOnAMessageWithCallBack').withArgs('message').and.callFake(()=>{});
let username = await service.getUsername();
expect(username).toBe('username');
expect(stripDomain).toHaveBeenCalledTimes(1);
});
我在 运行 测试时遇到以下错误:
间谍 'listenOnAMessageWithCallBack' 收到一个带有参数 [ 'catchUser', 函数 ] 的调用,但所有配置的策略都指定了其他参数。
如何模拟回调函数及其调用函数?
提前致谢。
您收到该错误消息是因为您使用 .withArgs('message')
配置了 listenOnAMessageWithCallBack
间谍,因此如果使用参数 'message'
。但是,在您的服务代码中,该方法是使用 'catchUser'
和回调函数而不是 'message'
调用的,因此永远不会调用您的间谍。如果您删除 .withArgs('message')
条件,您的间谍将被调用,而不管传递给实际方法的参数如何。
一旦你让它工作并调用你的间谍,然后在间谍的 callFake
函数中,你可以获取正在传递到你的服务代码中的方法的回调:
spyOn(electronController, 'listenOnAMessageWithCallBack').and.callFake(
(msg, cb) => {
expect(msg).toBe('catchUser');
expect(typeof cb).toBe('function');
// cb here is the cb being passed into listenOnAMessageWithCallBack in your service
// code, so you need to invoke it here yourself or the promise won't get resolved
cb('mockEvent', 'mockUsername');
}
);
您不能真正模拟回调,因为它是您服务中的局部变量,但由于您可以获取它并在测试中手动调用它,您应该能够测试它的效果。
不过,您需要弄清楚您希望代码做什么,因为该回调将 service.username
设置为传递给它的用户名,但看起来在您的测试中您是试图监视 service.stripDomain
并改为设置 service.username
。所以看起来您需要准确确定您要在此处测试的内容。
Here's a stackblitz 显示 callFake
正在工作并允许您访问回调函数。
我有一个 returns 承诺并调用另一个函数的函数,该函数将回调作为参数,但我无法弄清楚如何模拟回调函数或调用它的函数。
我要模拟的函数 "listenOnAMessageWithCallBack" 来自我正在注入的服务,我还想模拟它调用的回调函数。
我的实现:
async getUsername(): Promise<string> {
return await new Promise<string>((resolve, reject) => {
try {
this.electronController.sendMessage('userName');
let cb = (event, username) =>{
this.username = username;
let user = this.stripDomain(this.username);
resolve(user);
};
this.electronController.listenOnAMessageWithCallBack('catchUser', cb);
} catch (err) {
reject(err);
}
})
}
我的测试如下:
it('testing function with callback', async() => {
const stripDomain = spyOn(service, 'stripDomain').and.callFake(()=>{
service.username = service.username.split('\').reverse()[0];
return service.username;
});
let cb = (event, username)=>{Promise.resolve('username')}
spyOn(electronController, 'listenOnAMessageWithCallBack').withArgs('message').and.callFake(()=>{});
let username = await service.getUsername();
expect(username).toBe('username');
expect(stripDomain).toHaveBeenCalledTimes(1);
});
我在 运行 测试时遇到以下错误: 间谍 'listenOnAMessageWithCallBack' 收到一个带有参数 [ 'catchUser', 函数 ] 的调用,但所有配置的策略都指定了其他参数。
如何模拟回调函数及其调用函数?
提前致谢。
您收到该错误消息是因为您使用 .withArgs('message')
配置了 listenOnAMessageWithCallBack
间谍,因此如果使用参数 'message'
。但是,在您的服务代码中,该方法是使用 'catchUser'
和回调函数而不是 'message'
调用的,因此永远不会调用您的间谍。如果您删除 .withArgs('message')
条件,您的间谍将被调用,而不管传递给实际方法的参数如何。
一旦你让它工作并调用你的间谍,然后在间谍的 callFake
函数中,你可以获取正在传递到你的服务代码中的方法的回调:
spyOn(electronController, 'listenOnAMessageWithCallBack').and.callFake(
(msg, cb) => {
expect(msg).toBe('catchUser');
expect(typeof cb).toBe('function');
// cb here is the cb being passed into listenOnAMessageWithCallBack in your service
// code, so you need to invoke it here yourself or the promise won't get resolved
cb('mockEvent', 'mockUsername');
}
);
您不能真正模拟回调,因为它是您服务中的局部变量,但由于您可以获取它并在测试中手动调用它,您应该能够测试它的效果。
不过,您需要弄清楚您希望代码做什么,因为该回调将 service.username
设置为传递给它的用户名,但看起来在您的测试中您是试图监视 service.stripDomain
并改为设置 service.username
。所以看起来您需要准确确定您要在此处测试的内容。
Here's a stackblitz 显示 callFake
正在工作并允许您访问回调函数。