Jasmine:测试一个函数,使用jasmine从不同的函数调用

时间:2016-12-28 23:30:15

标签: javascript unit-testing jasmine jasmine-jquery

我在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();
     }
};

我正在尝试测试调用getSomeUrl()方法时将调用foo()方法。

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

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,所以我实际上不会调用bar.getSomeUrl()window.foo()
  2. 所以我想我应该这样做,如下所示:

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

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

    然而,当我这样做时,测试失败,我收到以下错误:

    Error: Expected a spy, but got Function.

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

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

    没有改变任何事情

    我现在只使用Jasmine和Javascript几天,并且对事情的运作方式有了广泛的了解。

    非常感谢任何建议让这个测试通过,并指出我做错了什么。

1 个答案:

答案 0 :(得分:0)

首先,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();    
    });
 });