【问题标题】:Can I call the original method inside the supplied function to "andCallFake" of a Jasmine spy?我可以将提供的函数中的原始方法调用为 Jasmine 间谍的“andCallFake”吗?
【发布时间】:2019-02-13 21:24:40
【问题描述】:

我可以将原始方法保存在 beforeEach 中的变量中,然后在 afterEach 中恢复它,但也许我可以使用会在测试套件之间自动重置的 spy。

spyOn(Ext, "create").andCallFake(function(className){
    if (className === 'Waf.view.Viewport')
        // call the original Ext.create method
});

这可能吗?我正在使用 Jasmine 1.3

【问题讨论】:

    标签: jasmine


    【解决方案1】:

    可以将原方法绑定到fake中:

    var obj = {
      method: function(name) { return name + '!'; }
    }
    
    var methodFake = function(original, name) {
      return 'faked ' + original(name);
    }.bind(obj, obj.method)
    spyOn(obj, 'method').andCallFake(methodFake);
    
    obj.method('hello') // outputs 'faked hello!'
    

    对于它的价值,我认为这样做不是很好的做法,但是当我测试一些 d3 代码时,我最近遇到了这种需要。希望对您有所帮助。

    【讨论】:

    • 这正是 OP 在 2014 年所要求的,也是我今天所需要的,谢谢!
    【解决方案2】:

    这是 Jasmine 2.3 的 hack。理想情况下,假回调应该可以访问原始函数的引用以根据需要调用,而不是像这样到处乱跳。

    鉴于可以在 Jasmine 2.3 中修改存根策略on the fly,以下方法似乎也有效:

    var createSpy = spyOn(Ext, "create");
    createSpy.and.callFake(function(className){
        if (className === 'Waf.view.Viewport'){
            createSpy.and.callThrough();
            Ext.create(className);        
        }
    });
    

    【讨论】:

      【解决方案3】:

      这是我使用 Jasmine 和 Angular 服务实现它的方法。我正在监视的服务正在我的测试服务的构造函数中被调用:

      // create the TestBed:
      TestBed.configureTestingModule({
          providers: [MyInjectedService, ServiceConstructorInjectedService]
      });
      myInjectedService = TestBed.get(MyInjectedService);
      serviceConstructorInjectedService = TestBed.get(ServiceConstructorInjectedService);
      
      it('should...', () => {
          let returnValue = 'return this';
          spyOn(serviceConstructorInjectedService , 'myFunction').and.callFake((param) => {
              if (param === 'testValue') {
                  return returnValue;
              } else {
                  return ServiceConstructorInjectedService.prototype.myFunction(param);
              }
          });
      });
      
      // instantiate the service again so spy is called
      myInjectedService = new MyInjectedService(
          TestBed.get(ServiceConstructorInjectedService)
      );
      

      【讨论】:

        【解决方案4】:

        我最终做了这样的事情:

        var origFunc = Ext.create;
        spyOn(Ext, "create").andCallFake(function(className, classConfig){
            if (className === 'Waf.view.Viewport') {
                 return {};
            } else {
                 return origFunc.apply(null, arguments);
            }
        });
        

        【讨论】:

          【解决方案5】:

          不同的场景应该相互独立地进行测试。尝试将您的测试构造成这样。

          beforeEach(function () {
              spyOn(Ext, 'create');
          });
          
          describe('scenario 1', function () {
              beforeEach(function () {
                  Ext.create.andCallThrough();
              });
          
              it('should do something', function () {
                  // do your assertions
              });
          });
          
          describe('scenario 2', function () {
              beforeEach(function () {
                  Ext.create.andCallFake(function () {
                      // faked function
                  });
                  // or if you're always returning a constant value, use andReturn
                  // Ext.create.andReturn({});
              });
          
              it('should do something', function () {
                  // do your assertions
              });
          });
          

          【讨论】:

          • 谢谢,但答案似乎不是我的问题。
          猜你喜欢
          • 2015-01-09
          • 2013-05-10
          • 2017-02-08
          • 2014-04-24
          • 1970-01-01
          • 1970-01-01
          • 2013-04-18
          • 1970-01-01
          • 2014-03-26
          相关资源
          最近更新 更多