【问题标题】:How to test that my service returns data with jasmine and angularjs如何测试我的服务是否使用 jasmine 和 angularjs 返回数据
【发布时间】:2015-11-20 10:44:22
【问题描述】:

我已经开始使用 jasmine 在 angularjs 中测试我的控制器,但是在阅读了一些教程后我有点卡住了。

我有一个名为 jasmineController 的简单 angularjs 控制器

(function () {
    "use strict";

    var myAppModule = angular.module('myApp');

    myAppModule.controller('jasmineController', ['$scope', 'genericService',
        function ($scope, genericService) {
            $scope.name = 'Superhero';
            $scope.counter = 0;
            $scope.$watch('name', function (newValue, oldValue) {
                $scope.counter = $scope.counter + 1;
            });

            $scope.testPromise = function() {
                return genericService.getAll("dashboard", "currentnews", null, null, null);
            }

            $scope.getNewsItems = function () {
                genericService.getAll("dashboard", "currentnews", null, null, null).then(function (data) {

                    $scope.name = 'Superhero';
                    $scope.newsItems = data;

                });
            }

        }
    ]);
})();

在我的 jasmine 测试中,我想调用 getNewsItems 并检查它是否可以调用 genericService.getAll 以及是否为 $scope.newsItems 分配了一些数据。我知道我会模拟服务并且我不会真正调用它。

这是我的规格

describe("test", function () {
    // Declare some variables required for my test
    var controller, scope, genericService;

    // load in module
    beforeEach(module("myApp"));


    beforeEach(inject(function ($rootScope, $controller, _genericService_) {
        genericService = _genericService_;
        // assign new scope to variable
        scope = $rootScope.$new();
        controller = $controller('jasmineController', {
            '$scope': scope
        });
    }));
    it('sets the name', function () {
        expect(scope.name).toBe('Superhero');
    });

    it('should assign data to scope', function() {
        //var fakeHttpPromise = {success: function () { }};
        scope.getNewsItems();
        spyOn(genericService, 'getAll');
        expect(genericService.getAll).toHaveBeenCalledWith('dashboard', 'currentnews');
    });

});

我有一个 genericService.getall() 的间谍,但除此之外,我有点坚持检查我的范围变量是否被分配了一个值。

我也得到了这个堆栈跟踪:

Error: Expected spy getAll to have been called with [ 'dashboard', 'currentnews' ] but it was never called.
   at stack (file:///C:/Users/nickgowdy/Local%20Settings/Application%20Data/Microsoft/VisualStudio/12.0/Extensions/4sg2jkkc.gb4/TestFiles/jasmine/v2/jasmine.js:1441:11)
   at buildExpectationResult (file:///C:/Users/nickgowdy/Local%20Settings/Application%20Data/Microsoft/VisualStudio/12.0/Extensions/4sg2jkkc.gb4/TestFiles/jasmine/v2/jasmine.js:1408:5)
   at expectationResultFactory (file:///C:/Users/nickgowdy/Local%20Settings/Application%20Data/Microsoft/VisualStudio/12.0/Extensions/4sg2jkkc.gb4/TestFiles/jasmine/v2/jasmine.js:533:11)
   at Spec.prototype.addExpectationResult (file:///C:/Users/nickgowdy/Local%20Settings/Application%20Data/Microsoft/VisualStudio/12.0/Extensions/4sg2jkkc.gb4/TestFiles/jasmine/v2/jasmine.js:293:5)
   at addExpectationResult (file:///C:/Users/nickgowdy/Local%20Settings/Application%20Data/Microsoft/VisualStudio/12.0/Extensions/4sg2jkkc.gb4/TestFiles/jasmine/v2/jasmine.js:477:9)
   at Anonymous function (file:///C:/Users/nickgowdy/Local%20Settings/Application%20Data/Microsoft/VisualStudio/12.0/Extensions/4sg2jkkc.gb4/TestFiles/jasmine/v2/jasmine.js:1365:7)
   at Anonymous function (file:///C:/Projects/2013/AMT2015/AMT2015.WebAPP/Scripts/tests/controllers/dashboardControllerSpec.js:49:9)
   at attemptSync (file:///C:/Users/nickgowdy/Local%20Settings/Application%20Data/Microsoft/VisualStudio/12.0/Extensions/4sg2jkkc.gb4/TestFiles/jasmine/v2/jasmine.js:1759:9)
   at QueueRunner.prototype.run (file:///C:/Users/nickgowdy/Local%20Settings/Application%20Data/Microsoft/VisualStudio/12.0/Extensions/4sg2jkkc.gb4/TestFiles/jasmine/v2/jasmine.js:1747:9)
   at QueueRunner.prototype.execute (file:///C:/Users/nickgowdy/Local%20Settings/Application%20Data/Microsoft/VisualStudio/12.0/Extensions/4sg2jkkc.gb4/TestFiles/jasmine/v2/jasmine.js:1733:5)

【问题讨论】:

  • 您需要返回 genericService.getAll 进行测试,然后只有您可以测试
  • @ngLover 我必须打电话给:spyOn(genericService, 'getAll').andReturn(fakeHttpPromise) 吗?我之前的代码中有这个,但它也没有通过这个测试。
  • 也尝试将 null 传递给 toHaveBeenCalledWith
  • 从您的控制器中,您可以返回 genericService,这样您就可以使您的测试调用异步,然后可以检查要分配的范围变量
  • @ngLover 可以发布一些代码吗?我有点困惑。

标签: javascript angularjs jasmine chutzpah


【解决方案1】:

在调用测试函数之前,您需要先放置间谍。你实际上是在向服务函数传递更多参数。因此,您需要使用确切的参数列表进行测试。

it('should assign data to scope', function() {
        //var fakeHttpPromise = {success: function () { }};
        spyOn(genericService, 'getAll');
        scope.getNewsItems();
        expect(genericService.getAll).toHaveBeenCalledWith('dashboard', 'currentnews',null,null,null);
    });

【讨论】:

  • 你是对的,如果我调用 $scope.testPromise 我的测试通过但如果我调用 $scope.getNewsItems 它不会。我的控制器中的大多数角度代码都遵循 $scope.getNewsItems ,其中该函数不返回任何内容,但在代码中它将解析的承诺分配给另一个范围变量。
  • 你知道我将如何测试 getNewsItems 吗?据我所见,他们都使用 genericservice 但 getNewsItems 在 .then 之后有一个烦人的功能
【解决方案2】:

我最终这样做了:

describe("test", function () {
    // Declare some variables required for my test
    var controller, scope, genericService;

    // load in module
    beforeEach(module("myApp"));


    beforeEach(inject(function ($rootScope, $controller, _$q_, _genericService_) {
        genericService = _genericService_;
        var deferred = _$q_.defer();
        deferred.resolve('resolveData');
        spyOn(genericService, 'getAll').and.returnValue(deferred.promise);

        scope = $rootScope.$new();
        controller = $controller('jasmineController', {
            '$scope': scope
        });
    }));
    it('sets the name', function () {
        expect(scope.name).toBe('Superhero');
    });

    it('should assign data to scope', function() {
        //spyOn(genericService, 'getAll').and.callFake(function() {

        //});
        scope.getNewsItems();
        scope.$apply();
        expect(scope.newsItems).toBe('resolveData');
        //expect(genericService.getAll).toHaveBeenCalledWith('dashboard', 'currentnews', null, null, null);

    });

});

因为我的测试不仅仅是调用一个服务,而是处理一个承诺,我不得不注入 $q。然后用 spy on 我说调用服务和方法,返回值是延迟的承诺。

最后我可以查看作用域变量,看看是否有任何东西被这行赋值:

expect(scope.newsItems).toBe('resolveData');

感谢所有提供帮助的人。

【讨论】:

    猜你喜欢
    • 2012-10-12
    • 2014-05-19
    • 2016-10-02
    • 2014-06-17
    • 2016-06-17
    • 2014-06-19
    • 2013-11-03
    • 1970-01-01
    • 2014-07-05
    相关资源
    最近更新 更多