admin管理员组文章数量:1356965
I have a function that returns a promise and calls another function which takes a call back as a parameter but I'm unable to to figure how to mock the callback function nor the function calling it.
The function I'm trying to mock is "listenOnAMessageWithCallBack" from a service I'm injecting and I also want to mock the callback function that it calls.
My implementation:
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);
}
})
}
and my test is the following:
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);
});
I'm getting the following error when I run the test: Spy 'listenOnAMessageWithCallBack' received a call with arguments [ 'catchUser', Function ] but all configured strategies specify other arguments.
How can I mock the callback function and its calling function ?
Thanks in advance.
I have a function that returns a promise and calls another function which takes a call back as a parameter but I'm unable to to figure how to mock the callback function nor the function calling it.
The function I'm trying to mock is "listenOnAMessageWithCallBack" from a service I'm injecting and I also want to mock the callback function that it calls.
My implementation:
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);
}
})
}
and my test is the following:
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);
});
I'm getting the following error when I run the test: Spy 'listenOnAMessageWithCallBack' received a call with arguments [ 'catchUser', Function ] but all configured strategies specify other arguments.
How can I mock the callback function and its calling function ?
Thanks in advance.
Share Improve this question asked Jan 10, 2020 at 17:28 mahmoud chebbanimahmoud chebbani 751 gold badge2 silver badges7 bronze badges 1- i was only looking to stub out a method with some custom implementation and stumbled on this post and the callFake idea used in the question helped. – oomer Commented Jul 14, 2021 at 12:55
1 Answer
Reset to default 6You're getting that error message because you configured your listenOnAMessageWithCallBack
spy with .withArgs('message')
, so your spy will only be used in place of that method if that method is called with argument 'message'
. However, in your service code that method is called with 'catchUser'
and a callback function, not with 'message'
, so your spy is never invoked. If you remove the .withArgs('message')
condition your spy will be invoked regardless of the arguments passed to the actual method.
Once you get that working and your spy is invoked, then within the spy's callFake
function you can get a hold of the callback that's being passed into the method in your service code:
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');
}
);
You can't really mock the callback because it's a local variable within your service, but since you can get a hold of it and manually invoke it in your test, you should be able to test its effects.
You'd need to figure out exactly what you expect your code to be doing, though, because that callback sets service.username
to the username passed to it, but it looks like in your test you're trying to spy on service.stripDomain
and have that set service.username
instead. So it looks like you need to determine exactly what you're trying to test here.
Here's a stackblitz showing the callFake
working and giving you access to the callback function.
版权声明:本文标题:javascript - How to mock a callback function to test a promise in with jasmine in Angular 8 - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1744058193a2583640.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论