javascript 有什么方法可以根据参数修改茉莉花间谍?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/16198353/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-27 03:40:19  来源:igfitidea点击:

Any way to modify Jasmine spies based on arguments?

javascriptunit-testingjasmine

提问by Jmr

I have a function I'd like to test which calls an external API method twice, using different parameters. I'd like to mock this external API out with a Jasmine spy, and return different things based on the parameters. Is there any way to do this in Jasmine? The best I can come up with is a hack using andCallFake:

我有一个函数我想测试它使用不同的参数两次调用外部 API 方法。我想用 Jasmine 间谍模拟这个外部 API,并根据参数返回不同的东西。有没有办法在茉莉花中做到这一点?我能想到的最好的方法是使用 andCallFake 进行黑客攻击:

var functionToTest = function() {
  var userName = externalApi.get('abc');
  var userId = externalApi.get('123');
};


describe('my fn', function() {
  it('gets user name and ID', function() {
    spyOn(externalApi, 'get').andCallFake(function(myParam) {
      if (myParam == 'abc') {
        return 'Jane';
      } else if (myParam == '123') {
        return 98765;
      }
    });
  });
});

回答by Andreas K?berle

In Jasmine versions 3.0 and above you can use withArgs

在 Jasmine 3.0 及以上版本中,您可以使用 withArgs

describe('my fn', function() {
  it('gets user name and ID', function() {
    spyOn(externalApi, 'get')
      .withArgs('abc').and.returnValue('Jane')
      .withArgs('123').and.returnValue(98765);
  });
});

For Jasmine versions earlier than 3.0 callFakeis the right way to go, but you can simplify it using an object to hold the return values

对于早于 3.0 的 Jasmine 版本callFake是正确的方法,但您可以使用对象来简化它来保存返回值

describe('my fn', function() {
  var params = {
    'abc': 'Jane', 
    '123': 98765
  }

  it('gets user name and ID', function() {
    spyOn(externalApi, 'get').and.callFake(function(myParam) {
     return params[myParam]
    });
  });
});

Depending on the version of Jasmine, the syntax is slightly different:

根据 Jasmine 的版本,语法略有不同:

  • 1.3.1: .andCallFake(fn)
  • 2.0: .and.callFake(fn)
  • 1.3.1: .andCallFake(fn)
  • 2.0: .and.callFake(fn)

Resources:

资源:

回答by akhouri

You could also use $provideto create a spy. And mock using and.returnValuesinstead of and.returnValueto pass in parameterised data.

你也可以$provide用来创建一个间谍。并模拟使用and.returnValues而不是and.returnValue传入参数化数据。

As per Jasmine docs:By chaining the spy with and.returnValues, all calls to the function will return specific values in order until it reaches the end of the return values list, at which point it will return undefined for all subsequent calls.

根据 Jasmine 文档:通过将 spy 与 链接起来and.returnValues,对该函数的所有调用将按顺序返回特定值,直到到达返回值列表的末尾,此时它将为所有后续调用返回 undefined。

describe('my fn', () => {
    beforeEach(module($provide => {
        $provide.value('externalApi', jasmine.createSpyObj('externalApi', ['get']));
    }));

        it('get userName and Id', inject((externalApi) => {
            // Given
            externalApi.get.and.returnValues('abc','123');

            // When
            //insert your condition

            // Then
            // insert the expectation                
        }));
});

回答by Guillermo

In my case, I had a component I was testing and, in its constructor, there is a config service with a method called getAppConfigValuethat is called twice, each time with different arguments:

就我而言,我有一个正在测试的组件,在它的构造函数中,有一个配置服务,其中包含一个名为getAppConfigValue的方法,该方法被调用两次,每次使用不同的参数:

constructor(private configSvc: ConfigService) {
  this.configSvc.getAppConfigValue('a_string');
  this.configSvc.getAppConfigValue('another_string');
}

In my spec, I provided the ConfigService in the TestBed like so:

在我的规范中,我在 TestBed 中提供了 ConfigService,如下所示:

{
  provide: ConfigService,
  useValue: {
    getAppConfigValue: (key: any): any {
      if (key === 'a_string) {
        return 'a_value';
      } else if (key === 'another_string') {
        return 'another_value';
      }
    }
  } as ConfigService
}

So, as long as the signature for getAppConfigValueis the same as specified in the actual ConfigService, what the function does internally can be modified.

所以,只要getAppConfigValue的签名与实际的ConfigService中指定的一致,函数内部的作用是可以修改的。