【问题标题】:Jasmine: Testing a function, being called from a different function using jasmineJasmine:测试一个函数,使用 jasmine 从另一个函数调用
【发布时间】:2017-05-13 06:34:18
【问题描述】:

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

    expect(window.foo).toHaveBeenCalled();

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

但是,当我这样做时,测试失败并出现以下错误:

Error: Expected a spy, but got Function.

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

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

什么都没变

我使用 Jasmine 和 Javascript 才几天,并且对事物的工作原理有了广泛的了解。

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

【问题讨论】:

  • 它与 java 无关。 Javascript是一个单词拼写的,和Java没有关系。
  • 处理好了。谢谢。
  • 您有语法错误。 bar.getSomeUrl 是一个对象字面量(语法无效)。这不是一个函数

标签: javascript unit-testing jasmine jasmine-jquery


【解决方案1】:

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

【讨论】:

  • 谢谢。我已经将bar.getSomeUrl 实现为一个函数。发布问题时打错字了。
  • 尝试了这个建议。没有帮助。最终还是重定向到someUrl
  • 好的,我在浏览器中调试了测试运行器,发现我遇到了异常:Mock clock is not installed. 我重新构建了项目并再次尝试,一切似乎都正常。谢谢@Phil。那么测试失败是因为调用了 setTimeout 函数吗?
猜你喜欢
  • 2016-05-27
  • 2018-09-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-09-03
  • 1970-01-01
相关资源
最近更新 更多