如何监视在每个代码块之前在 Jasmine 中创建的函数?

How to spyOn a function created inside the Jasmine beforeEach block of code?

这是我的代码:

describe('Factory: BaseService', function() {
    var fctry, mockBackend;

    beforeEach(function() {

        module('BaseApp');

        cb = function() {};

        inject(function(_BaseService_, _$httpBackend_) {
            mockBackend = _$httpBackend_;
            BaseService = _BaseService_;
        });
    });

    it('logout() should POST to /logout', function() {
        spyOn(BaseService, 'accessErrors').and.callThrough();
        spyOn('cb');
        mockBackend.expectPOST("/logout").respond(404, {msg: 'Not Found'});

        BaseService.logout(cb);

        mockBackend.flush();

        expect(BaseService.accessErrors).toHaveBeenCalled();
        expect(BaseService.cerrorMessages).toEqual(['Not Found']);
        expect(cb).toHaveBeenCalled();
    });
});

当我 运行 这个测试时,我收到一条错误消息:

Chromium 48.0.2564 (Ubuntu 0.0.0) Factory: BaseService logout() should POST to /logout FAILED
    Error: No method name supplied

它指向行spyOn('cb')。监视在 beforeEach 代码块中创建的函数的正确方法是什么?

你只能监视一个对象,这就是为什么 spyOn 的语法是:

objFoo = {};
objFoo.funcBar = function() {};

spyOn(objFoo, 'funcBar');

因此创建一个对象来包含您的函数。

或监视 window,因为您将 cb 设为全局变量:

spyOn(window, 'cb');

虽然这不是真的推荐:-)

通常,spyOn 应该用于删除依赖项 -- 监视在测试本身中定义的函数对我来说似乎很奇怪。

在这种情况下,我可能只是创建一个间谍并将其直接传递给 BaseService.logout

it('logout() should POST to /logout', function() {
    spyOn(BaseService, 'accessErrors').and.callThrough();

    // just create the spy here -- no need to create a function so you can replace
    // it with a spy via spyOn :-).
    var cb = jasmine.createSpy('cb');

    mockBackend.expectPOST("/logout").respond(404, {msg: 'Not Found'});

    BaseService.logout(cb);

    mockBackend.flush();

    expect(BaseService.accessErrors).toHaveBeenCalled();
    expect(BaseService.cerrorMessages).toEqual(['Not Found']);
    expect(cb).toHaveBeenCalled();
});