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

时间:2022-03-09 16:55:41

I'm trying to get started with karma-jasmine and I'm wondering why this test fails:

我正试图从karma-jasmine开始,我想知道为什么这个测试失败了:

it("should call fakeFunction", function() {
    spyOn(controller, 'addNew');
    spyOn(controller, 'fakeFunction');
    controller.addNew();
    expect(controller.fakeFunction).toHaveBeenCalled();
});

In my controller that I've previously set up for this test I have the following:

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

function addNew() {
    fakeFunction(3);
}

function fakeFunction(number) {
    return number;
}

both addNew and fakeFunction are exposed using:

addNew和fakeFunction都公开使用:

vm.addNew = addNew;
vm.fakeFunction = fakeFunction;

The test, however, fails with the following:

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

Expected spy fakeFunction to have been called.

预期的间谍伪装功能已经被调用。

I can make the test pass if I call the function from within my test. I was hoping, however, I could test if fakeFunction was called by another function. What is the proper way to achieve this?

如果我在测试中调用函数,我可以进行测试。但是,我希望可以测试fakeFunction是否由另一个函数调用。达到这一目标的正确方法是什么?

Update:

更新:

//test.js

beforeEach(function() {

    module("app");

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

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

    });

});

If I test something like:

如果我测试如下:

it('should say hello', function() {
    expect(controller.message).toBe('Hello');
});

The test passes if I put the following in my controller:

测试通过,如果我在控制器中执行以下操作:

var vm = this;
vm.message = 'Hello';

I just want to know how I can test if a public function was called from another function.

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

2 个解决方案

#1


9  

Your addNew method is calling fakeFunction. However, it is not calling controller.fakeFunction, which is what your expectation is.

你的addNew方法正在调用fakeFunction。但是,它没有调用controller。fakeFunction,这就是你的期望。

You'll need to change your code to use your controller, rather than these independent functions.

您需要更改代码来使用控制器,而不是使用这些独立的函数。

EDIT: You also need to not spy on your addNew function. This is causing the function to be replaced with a spy. The other alternative is to change it to:

编辑:您还需要不监视您的addNew函数。这导致函数被替换为一个间谍。另一种选择是将其改为:

spyOn(controller, 'addNew').and.callThrough()

#2


8  

I just came across this problem myself. The previous answer by @Vadim has the right principles but I don't think everything was very clear. In my case, I am trying to call a public function on a service from within another function. Here are the relevant snippets:

我自己也遇到过这个问题。@Vadim的前一个答案有正确的原则,但我不认为一切都很清楚。在我的例子中,我试图从另一个函数中调用服务的公共函数。以下是相关的片段:

Service:

服务:

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

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

    function publicMethod(){
      // Do stuff
    }

    var service = {
      publicMethod: publicMethod
    };

    return service;
});

Test:

测试:

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

  // Run stuff to trigger doSomething()

  expect(service.publicMethod).toHaveBeenCalled();
});

The key here is that the function being tested needs to be calling the same reference as the public function that is being spy'd on.

这里的关键是正在测试的函数需要调用与正在监视的公共函数相同的引用。

#1


9  

Your addNew method is calling fakeFunction. However, it is not calling controller.fakeFunction, which is what your expectation is.

你的addNew方法正在调用fakeFunction。但是,它没有调用controller。fakeFunction,这就是你的期望。

You'll need to change your code to use your controller, rather than these independent functions.

您需要更改代码来使用控制器,而不是使用这些独立的函数。

EDIT: You also need to not spy on your addNew function. This is causing the function to be replaced with a spy. The other alternative is to change it to:

编辑:您还需要不监视您的addNew函数。这导致函数被替换为一个间谍。另一种选择是将其改为:

spyOn(controller, 'addNew').and.callThrough()

#2


8  

I just came across this problem myself. The previous answer by @Vadim has the right principles but I don't think everything was very clear. In my case, I am trying to call a public function on a service from within another function. Here are the relevant snippets:

我自己也遇到过这个问题。@Vadim的前一个答案有正确的原则,但我不认为一切都很清楚。在我的例子中,我试图从另一个函数中调用服务的公共函数。以下是相关的片段:

Service:

服务:

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

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

    function publicMethod(){
      // Do stuff
    }

    var service = {
      publicMethod: publicMethod
    };

    return service;
});

Test:

测试:

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

  // Run stuff to trigger doSomething()

  expect(service.publicMethod).toHaveBeenCalled();
});

The key here is that the function being tested needs to be calling the same reference as the public function that is being spy'd on.

这里的关键是正在测试的函数需要调用与正在监视的公共函数相同的引用。