用于测试控制器的模拟角度服务

时间:2015-10-12 02:01:56

标签: angularjs rest maven unit-testing jasmine

让我先介绍一下情景。

这是我的角度代码。

//this is my controller
function viewUserProfile($scope, $http, svcUserInfo) {
    svcUserInfo.userInfo(null, function(data) {
        $scope.profile = loadProfile(data);
    }, function() {
        Console.log('Error getting User info.');
    });
}

所以基本上我只是使用svcUserInfo REST服务在$ scope.profile上加载一个配置文件对象(例如名字,姓氏等)。

服务的创建方式如下:

anythingHere.factory('svcUserInfo', ['$resource', function($resource) {
        return $resource(SVC_USER, null, {
            userInfo: {method: 'GET'}
        });
    }]);

现在这个工作完美,所以只需要在这些代码之前和之后假设其他声明或初始化。

现在我正在使用jasmine-maven-plugin编写测试代码 我想要实现的是使用和填充$ scope.profile来模拟服务。这就是我到目前为止所做的:

describe('User Profile Controller', function() {
    var rootScope, scope, 
    location = {}, route = {}, http = {}, userProfCtrl, 
    mockSvcUserInfo, userInfoPromise;

    beforeEach(module('myApp'));
    beforeEach(module(MOD_USERPROF));
    beforeEach(module(function($provide){
        $provide.factory('svcUserInfo', ['$q', function($q) {
            var profile = {
                nameType: 'Personal Name',
                firstName: 'Joseph',
                lastName: 'Bada',
                email: 'email@email.com',
                hasReferrer: false,
                referrer: null,
                country: 'myCountry',
                state: 'myState',
                city: 'myCIty',
                address1: 'this is address1',
                address2: 'this is address2',
                zipcode: '9999',
                phone: '+191234567',
                maxProduct: '2'
            };
          function userInfo(data){
            if(userInfoPromise){
              return $q.when(profile);
            } else {
              return $q.reject();
            }
          }
          return{
            userInfo: userInfo
          };
        }]);
    }));
    beforeEach(inject(function($rootScope, $controller, svcUserInfo){
        scope = $rootScope.$new();
        rootScope = $rootScope.$new();
        mockSvcUserInfo = svcUserInfo;
        spyOn(mockSvcUserInfo, 'userInfo').and.callThrough();
        userProfCtrl = $controller(CTRL_USERPROF, {
            $scope: scope,
            svcUserInfo: mockSvcUserInfo,
            $rootScope: rootScope
        });
    }));
    it('should call the rest service for User Profile and populate profile', function() {
        userInfoPromise = true;
        scope.$digest();
        rootScope.$digest();
        expect(mockSvcUserInfo.userInfo).toHaveBeenCalled();
        expect(scope.profile).not.toBe(undefined); // or undefined anything like these
        it("profile object: " + JSON.stringify(scope.profile)); // this is for debugging purposes so that i can check if scope.profile has values or not.
    });
});

现在在规范上我希望在调用mockSvcUserInfo.user之后。 然后必须填充/初始化scope.profile,因为根据我在控制器上的代码,在成功调用服务时,必须填充$ scope.profile。 到目前为止,结果是scope.profile未定义

我从这里开始测试代码: http://www.sitepoint.com/mocking-dependencies-angularjs-tests/#mocking-methods-returning-promises

请帮助我,谢谢

修改 我已经更新了第一个答案的代码

it('should call the rest service for User Profile', inject(function($rootScope,$controller,svcUserInfo) {
    scope = $rootScope.$new();
    rootScope = $rootScope.$new();
    userInfoPromise = true;
    mockSvcUserInfo = svcUserInfo;
    spyOn(mockSvcUserInfo, 'userInfo').and.callThrough();
    userProfCtrl = $controller(CTRL_USERPROF, {
        $scope: scope,
        svcUserInfo: mockSvcUserInfo,
        $rootScope: rootScope
    });
    scope.$digest();
    rootScope.$digest();
    expect(mockSvcUserInfo.userInfo).toHaveBeenCalled();
    expect(scope.profile).not.toBe([]);
    it("hello" + JSON.stringify(scope.profile));
}));

仍然是scope.profile未定义

1 个答案:

答案 0 :(得分:0)

我想我知道这个问题。

您在测试中将userInfoPromise设置为true,但您的控制器是在设置过程中创建的,当您设置布尔值时,服务调用已完成。

userInfoPromise内设置beforeeach或将控制器创建移动到测试中。