简体   繁体   English

如何模拟回调函数以在 Angular 8 中使用茉莉花测试承诺

[英]How to mock a callback function to test a promise in with jasmine in Angular 8

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.我试图模拟的函数是来自我正在注入的服务的“listenOnAMessageWithCallBack”,我还想模拟它调用的回调函数。

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.运行测试时出现以下错误: Spy 'listenOnAMessageWithCallBack' 收到一个带有参数 [ 'catchUser', Function ] 的调用,但所有配置的策略都指定了其他参数。

How can I mock the callback function and its calling function ?如何模拟回调函数及其调用函数?

Thanks in advance.提前致谢。

You'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' .您收到该错误消息是因为您使用.withArgs('message')配置了您的listenOnAMessageWithCallBack间谍,因此如果使用参数'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.但是,在您的服务代码中,使用'catchUser'和回调函数调用该方法,而不是使用'message'调用,因此永远不会调用您的间谍。 If you remove the .withArgs('message') condition your spy will be invoked regardless of the arguments passed to the actual method.如果删除.withArgs('message')条件,则无论传递给实际方法的参数如何,都将调用您的 spy。

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:一旦你开始工作并且你的 spy 被调用,那么在 spy 的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');
  }
);

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.不过,您需要确切地弄清楚您希望代码做什么,因为该回调将service.username设置为传递给它的用户名,但看起来在您的测试中您正试图监视service.stripDomain并改为设置service.username 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. 这是一个堆栈闪电战,显示了callFake工作并让您访问回调函数。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM