【问题标题】:Mocking an Angular Repository with SinonJs使用 SinonJs 模拟 Angular 存储库
【发布时间】:2014-07-15 23:40:04
【问题描述】:

我对 Angular \SinonJS 有点陌生,所以请原谅这个愚蠢的问题,如果这很明显,请耐心等待。我做了一些谷歌搜索,似乎找不到答案。我使用 SinonJs 进行模拟,正如 Pluralsight 视频中推荐的那样。不确定它是否是最佳选择。欢迎任何替代品。

我想测试我的 AngularJS 控制器的行为并测试它是否使用我只指定一次的条件调用我的存储库搜索方法。

我的控制器中有以下内容,我的 Jasmin 测试运行程序中出现错误:

目标控制器.js:

stepByStepApp.controller("goalController", function ($scope, goalRepository) {

    $scope.viewGoalButtonDisabled = true;

    $scope.search = function (criteria) {
        $scope.errors = [];
        return goalRepository.search(criteria).$promise.then(
            function (goals) {
                $scope.viewGoalButtonDisabled = true;
                return goals;
            },
            function (response) {
                $scope.viewGoalButtonDisabled = true;
                $scope.errors = response.data;
            });
    };

});

目标控制器测试.js

'use strict';

(function () {
    describe('Given a Goal Controller', function () {
        var scope, controller, goalRepositoryMock, goals, criteria;

        beforeEach(function () {
            module('stepByStepApp');

            inject(function ($rootScope, $controller, goalRepository) {
                scope = $rootScope.$new();
                goalRepositoryMock = sinon.mock(goalRepository);

                goals = [{ foo: 'bar' }];
                criteria = 'test search criteria';

                controller = $controller('goalController', { $scope: scope });
            });
        });

        it('the View Goal Button should be disabled', function () {
            expect(scope.viewGoalButtonDisabled).toBe(true);
        });

        describe("when a goal is searched for, it", function () {

            it("should search the Goal Repository", function () {
                goalRepositoryMock.expects('search').once().returns(goals);

                scope.search(criteria);

                goalRepositoryMock.verify();
            });
        });
    });
}())

我收到以下错误:

2 specs, 1 failure 
Given a Goal Controller
    when a goal is searched for, it
        should search the Goal Repository 
        TypeError: Cannot read property 'then' of undefined

我显然没有正确地嘲笑对“goalRepository.search(criteria).$promise.then”的调用。如何正确模拟 $promise 和 .then ?提前致谢。

【问题讨论】:

    标签: angularjs mocking jasmine sinon


    【解决方案1】:

    我假设这个存储库正在返回一个资源对象。话虽如此,这就是我将如何测试这个控制器。

    这是工作的plunk

    Initial beforeEach 块

    您需要模拟出承诺链。为此,您需要注入 $q 服务。以下是我的全班 beforeEach 声明。我使用存根进行模拟。我将该模拟注入到我正在测试的控制器中。

    beforeEach(inject(function($controller, $rootScope, $q) {
    
       q = $q
    
       scope = $rootScope;
    
       goalRepositoryStub = sinon.stub({
         search: function() {}
       });
    
       testCtrl = $controller("goalController", {
         $scope: scope,
         goalRepository: goalRepositoryStub
       });
    }));
    

    有了这个模拟存储库,我现在可以完全控制它的作用。

    beforeEach 用于测试回购

    在这个块中,我实际上模拟了整个 Promise 链。我从 q 服务中获得了一个 defer 对象。从中我得到一个承诺。然后我把这个承诺放在一个虚假的资源对象中。然后,每当调用 search 时,我都会返回该假资源对象。然后我调用范围搜索。

    beforeEach(function() {
      deferred = q.defer();
      promise = deferred.promise;
      returnedResource = {
        $promise: promise
      };
    
    
      goalRepositoryStub.search.returns(returnedResource);
      scope.search(criteria);
    });
    

    实际测试

    对于实际测试,您需要告诉延迟对象要做什么(拒绝或解决承诺)并触发范围 $apply() 函数。然后你测试一下你的代码是否在做它应该做的事情。

    以下是我如何测试对 goalRepository 的成功调用的示例:

    describe('successful goalRepository call', function() {
      beforeEach(function() {
        deferred.resolve(dataToReturn);
        scope.$apply();
      });
    
      it('should add the data to scope.goals.', function() {
        expect(scope.goals).toBe(dataToReturn);
      });
    
      it('should not change scope.failureApi to true.', function() {
        expect(scope.viewGoalButtonDisabled).toBeFalsy();
      });
    });
    

    这些不是必要的“最佳做法”或任何东西。只是我发现自己解决这个特定问题的一种方法。

    【讨论】:

      猜你喜欢
      • 2021-08-06
      • 2014-02-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-03-24
      • 2018-06-28
      • 1970-01-01
      相关资源
      最近更新 更多