如何嘲笑$state.茉莉单元测试中的参数



我有以下控制器EditMeetingCtrl.js

(function() {
    'use strict';
    angular
        .module('myApp')
        .controller('EditMeetingCtrl', EditMeetingCtrl);
    EditMeetingCtrl.$inject = ['$rootScope', '$scope', '$state', '$http', '$translate',
        'meetingService', 'companyService', 'notificationService', 'meeting'];
function EditMeetingCtrl($rootScope, $scope, $state, $http, $translate, meetingService, companyService, notificationService, meeting) {
        $scope.meeting = meeting;
        $scope.companyId = $state.params.companyId;
        $scope.save = save;

        function save() {
            $scope.buttonDisable = true;
            meetingService.saveMeeting($state.params.companyId, $state.params.meetingId, $scope.meeting)
                .success(function(meetingId) {
                   //more code
                });
        }

}
})();

EditMeetingCtrlSpec.js测试用例

describe('in EditMeetingCtrl', function () {
    var companyService , meetingService ;
    meetingId = 123321 ;                      
    companyId = 456654 ;
    meetingObj = {} ;
    var fakeHttpPromise = {
                            success: function() {}
                          };
    beforeEach(angular.mock.module('myApp'));
    beforeEach(angular.mock.inject(function (_$httpBackend_, _companyService_ , _meetingService_) {
        $httpBackend = _$httpBackend_;
        companyService = _companyService_;
        meetingService = _meetingService_ ;
    }));
    describe('EditMeetingCtrl.save()', function () {
        var $rootScope, scope, $controller , $q  ;
        beforeEach(inject(function ($rootScope, $controller , _meetingService_ ) {
            scope = $rootScope.$new();
            createController = function() {
                return $controller('EditMeetingCtrl', {
                $scope: scope,
                meeting : {} ,
                meetingService : _meetingService_
                }); 
            };
            var controller = new createController();
        }));
        it("should save the meeting object", function() {
            spyOn(meetingService, 'saveMeeting').and.returnValue(fakeHttpPromise);
            scope.save();
            expect(meetingService.saveMeeting).toHaveBeenCalledWith( meetingId , companyId , meetingObj);
        });
    });
});

当尝试运行下面的测试用例EditMeetingCtrlSpec.js时,我得到了以下测试失败

PhantomJS 1.9.8 (Windows 8) EditMeetingCtrl Spying --> EditMeetingCtrl.save() should save the meeting FAILED
        Expected spy saveMeeting to have been called with [ 123321, 456654, Object({  }) ] but actual calls were [ undef
ined, undefined, Object({  }) ].

因此,理解这个问题的方法是,save()方法的服务调用包含$state.params.companyId, $state.params.meetingId参数,并在调用服务调用时发送undefined值。因此,我需要嘲笑$state.params。我不知道怎么做,谁能给我指个方向吗?

Michael Radionov Answer后编辑

describe('EditMeetingCtrl.save()', function () {
        var $rootScope, scope, $controller , $q  , $state ;
        beforeEach(inject(function ($rootScope, $controller , $state , _meetingService_ ) {
            scope = $rootScope.$new();
            createController = function() {
                return $controller('EditMeetingCtrl', {
                $scope: scope,
                meeting : {} ,
                meetingService : _meetingService_
                }); 
            };
            var controller = new createController();
        }));
        it("should save the meeting", function() {
            $state.params = { companyId: 123, meetingId: 567 };
            spyOn(meetingService, 'saveMeeting').and.returnValue(fakeHttpPromise);
            scope.save();
            //expect(meetingService.saveMeeting).toHaveBeenCalledWith( meetingId , companyId , meetingObj);
        });
    });

我已经完成了上面的操作,但是我得到以下错误说$state没有定义。

Firefox 38.0.0 (Windows 8.1) In EditMeetingCtrl EditMeetingCtrl.save() should save the meeting FAILED
        TypeError: $state is undefined in C:/Users/sal/Documents/myApp/test/meeting/EditMe
etingCtrlSpec.js (line 80)

我认为这是因为我没有这样做-> $state : state在注入方法,所以我试着这样做,但得到了同样的错误。

您可以模拟整个$state提供程序,然后在调用save:

之前准确指定您希望在params属性中使用的值。
describe('in EditMeetingCtrl', function () {
    // ...
    beforeEach(angular.mock.module('myApp'));
    beforeEach(angular.mock.module(function ($provide) {
        // mock the entire $state provider
        $provide.provider('$state', function () {
            return {
                $get: function () {
                    return {
                        // by default it will be an empty object
                        params: {}
                    };
                }
            };
        });
    }));
    // ....
    describe('EditMeetingCtrl.save()', function () {
        // inject mocked $state - one that you've provided above
        var $rootScope, scope, $controller, $q, state;
        // ---------------------------------------^^^
        beforeEach(inject(function ($rootScope, $controller, $state, _meetingService) {
            // ------------------------------------------------^^^
            state = $state;
        }));
        // ...
        it("should save the meeting object", function() {
            // provide custom params which will be used in a call
            state.params = { companyId: 123, meetingId: 567 };
            spyOn(meetingService, 'saveMeeting').and.returnValue(fakeHttpPromise);
            scope.save();
            expect(meetingService.saveMeeting).toHaveBeenCalledWith( meetingId , companyId , meetingObj);
        });
    });
    // ...
});

相关内容

  • 没有找到相关文章

最新更新