茉莉花:测试一个函数,使用茉莉花从不同的函数调用

Jasmine: Testing a function, being called from a different function using jasmine

我在 javascript 文件中有一个方法。

function foo() {
  setTimeout(function() {
      bar.getSomeUrl();
      },WAIT_FOR_SOMETIME);
}

现在getSomeUrl()实现如下。

var bar = {
     getSomeUrl : function(){
         window.location.href = 'someUrl';
         return;
     },
     anotherProp : function() {
         return bar.getSomeUrl();
     }
};

我正在尝试测试当我调用 foo() 方法时是否会调用 getSomeUrl() 方法。

我正在使用 jasmine 进行测试。我的茉莉花测试如下:

describe('This tests getSomeUrl()', function() {
    it('is called when foo() is called', function(){
        spyOn(bar,'getSomeUrl').and.callFake(function(){});

        window.foo();
        expect(bar.getSomeUrl).toHaveBeenCalled();

    });
 });

我真的不关心测试 getSomeUrl() 内部发生的事情,因为我有一个单独的测试。

我想测试的是,当我从某个地方调用我的 foo() 时,getSomeUrl() 被调用。

我有以下问题:

  1. 如果我这样做,测试会失败,并且在 运行 所有测试结束时,浏览器会重定向到 someUrl。我没想到会发生这种情况,因为我认为既然我在 bar.getSomeUrl() 上有一个间谍并且正在返回一个 fake method 它实际上不会在我调用 [=23] 时调用 bar.getSomeUrl() =].
  2. 所以我想也许我应该按如下方式进行:

    期待(window.foo).toHaveBeenCalled();

这没有意义,因为我正在尝试测试是否正在调用 bar.getSomeUrl()

然而,当我这样做时,测试失败并且出现以下错误:

Error: Expected a spy, but got Function.

我还认为可能是 setTimeout 函数导致了问题,并将 foo() 函数更改为:

function foo() {
    bar.getSomeUrl();
};

没有改变任何东西

我与 Jasmine 和 Javascript 一起工作才几天,对事情的运作方式有广泛的了解。

非常感谢任何使此测试通过的建议以及关于我做错了什么的指示。

首先,bar.getSomeUrl 应该是一个函数,而不是一个(无效的)对象

var bar = {
     getSomeUrl : function() {
         window.location.href = 'someUrl';
         return;
     },
     anotherProp : function() {
         return bar.getSomeUrl();
     }
};

其次,在测试带有超时的代码时使用Jasmine Clock

describe('This tests getSomeUrl()', function() {
    beforeEach(function() {
        jasmine.clock().install();
    });

    afterEach(function() {
        jasmine.clock().uninstall();
    });

    it('is called when foo() is called', function(){
        spyOn(bar,'getSomeUrl').and.callFake(function(){});

        foo();
        expect(bar.getSomeUrl).not.toHaveBeenCalled();

        jasmine.clock().tick(WAIT_FOR_SOMETIME);    
        expect(bar.getSomeUrl).toHaveBeenCalled();    
    });
 });