Jasmine spyOn - 方法在jQuery匿名函数中不存在

时间:2014-07-15 01:47:19

标签: javascript jquery jasmine

在SO和其他论坛上搜索过此问题的答案。没有找到解决方案。

我遇到了Jasmine无法在jQuery代码块中找到函数的问题,无论Jasmine代码是否在jQuery函数内部。

$(function() {
    function foo(param1, param2) {
        // some code
    }

    describe("Foo function", function () {

        spyOn(window, 'foo');

        foo(1, 2);

        it("Should be found by Jasmine", function(){
            expect(window.foo).toHaveBeenCalled();
        });
    });
});

Error: foo() method does not exist

我还尝试了spyOn($, 'foo')spyOn($.fn, 'foo')和其他人。

此外,以下代码也不起作用。

$(function() {
    function foo(param1, param2) {
        // some code
    }
});

describe("Foo function", function () {

    spyOn(window, 'foo');

    foo(1, 2);

    it("Should be found by Jasmine", function(){
        expect(window.foo).toHaveBeenCalled();
    });
});

那么如何使这两个代码块都能正常工作(即Jasmine代码在jQuery函数中,以及它在jQuery函数之外的位置)?

3 个答案:

答案 0 :(得分:2)

我讨厌回答我自己的问题,但我比其他人没有从错误中吸取教训。

这里有两个问题:

  1. Jasmine需要一个包含对象
  2. 您无法访问JS函数范围之外的函数/变量
  3. 1 - 茉莉花间谍需要使用一个包含物品,如果找不到,你只需要自己制作。所以下面的代码可以工作:

    // Using Jasmine inside of a jQuery anon function
    $(function () {
    
        function foo() {
            // Some code
        }
    
        describe("Foo function", function () {
    
            it("Should be findable by Jasmine", function () {
                var Thing = {}
                Thing.foo = foo;
                spyOn(Thing, 'foo');
                Thing.foo(2)
                expect(Thing.foo).toHaveBeenCalled();
            });
        });
    });
    

    2 - 如果你在jQuery anon函数之外有describe块,它就无法访问jQuery块中的任何值,因此上面的第二个代码示例赢得了'无论你做什么,都可以工作。

答案 1 :(得分:1)

不确定为什么你需要间谍为“私人”功能。您可以执行以下Demo

$(function(){
    function foo() {
        return 'foo';
    };

    function baz() {
        return foo();    
    }

    describe('foo', function() { 
        //create a spy and define it to change foo
        foo = jasmine.createSpy().andCallFake(foo);


        it('should be a function', function() {
            expect(typeof foo).toBe('function');             
        });        

        var result = baz(); //call function you want to test

        it('should be called', function() {            
            expect(foo).toHaveBeenCalled(); //check if foo was called by baz   
        });        

        //additional check for return since .andCallThrough won't work
        it('should return foo', function() { 
            expect(result).toBe('foo');    
        })

    });
});

答案 2 :(得分:0)

看起来你只需要以不同的方式设置你的jQuery函数。尝试...

(function ($) {
    $.fn.foo = function (param1, param2) {
        // some code
    };
}(jQuery));

然后你的Jasmine脚本看起来像......

describe("Foo function", function () {

    var test = spyOn($.fn, 'foo');

    $.fn.foo(1,2);

    it("Should be found by Jasmine", function(){
        expect(test).toHaveBeenCalled();
        expect(test).toHaveBeenCalledWith(1,2);
    });
});