AngularJS - 如何测试是否从另一个函数中调用函数?

Rap*_*nah 11 jasmine angularjs karma-runner karma-jasmine

我正在尝试使用karma-jasmine,我想知道为什么这个测试失败了:

it("should call fakeFunction", function() {
    spyOn(controller, 'addNew');
    spyOn(controller, 'fakeFunction');
    controller.addNew();
    expect(controller.fakeFunction).toHaveBeenCalled();
});
Run Code Online (Sandbox Code Playgroud)

在我之前为此测试设置的控制器中,我有以下内容:

function addNew() {
    fakeFunction(3);
}

function fakeFunction(number) {
    return number;
}
Run Code Online (Sandbox Code Playgroud)

二者addNewfakeFunction使用暴露:

vm.addNew = addNew;
vm.fakeFunction = fakeFunction;
Run Code Online (Sandbox Code Playgroud)

但是,测试失败的原因如下:

Expected spy fakeFunction to have been called.

如果我在测试中调用函数,我可以通过测试.我希望,但是,我可以测试是否fakeFunction被另一个函数调用.实现这个目标的正确方法是什么?

更新:

//test.js

beforeEach(function() {

    module("app");

    inject(function(_$rootScope_, $controller) {

        $scope = _$rootScope_.$new();
        controller = $controller("CreateInvoiceController", {$scope: $scope});

    });

});
Run Code Online (Sandbox Code Playgroud)

如果我测试类似的东西:

it('should say hello', function() {
    expect(controller.message).toBe('Hello');
});
Run Code Online (Sandbox Code Playgroud)

如果我在控制器中放入以下内容,则测试通过:

var vm = this;
vm.message = 'Hello';
Run Code Online (Sandbox Code Playgroud)

我只想知道如何测试是否从另一个函数调用了一个公共函数.

Vad*_*dim 10

你的addNew方法是打电话fakeFunction.但是,它没有打电话controller.fakeFunction,这是你的期望.

您需要更改代码才能使用控制器,而不是这些独立的功能.

编辑:你也需要不要监视你的addNew功能.这导致该功能被间谍取代.另一种方法是将其更改为:

spyOn(controller, 'addNew').and.callThrough()
Run Code Online (Sandbox Code Playgroud)


Ale*_*ite 8

我自己刚遇到这个问题.@Vadim先前的回答有正确的原则,但我不认为一切都很清楚.在我的情况下,我试图从另一个函数内调用服务上的公共函数.以下是相关摘要:

服务:

angular.module('myApp').factory('myService', function() {

    function doSomething() {
      service.publicMethod();
    }

    function publicMethod(){
      // Do stuff
    }

    var service = {
      publicMethod: publicMethod
    };

    return service;
});
Run Code Online (Sandbox Code Playgroud)

测试:

it('calls the public method when doing something', function(){
  spyOn(service, 'publicMethod');

  // Run stuff to trigger doSomething()

  expect(service.publicMethod).toHaveBeenCalled();
});
Run Code Online (Sandbox Code Playgroud)

这里的关键是被测试的函数需要调用与被窥探的公共函数相同的引用.