如何正确单元测试角度js控制器

时间:2014-07-26 06:40:06

标签: angularjs unit-testing jasmine

目前我在为角度控制器编写单元测试时遇到困难。我有一个$scope函数,它生成一个ajax请求,在解析所有promise之后,它将获取的数据分配给$scope.products。但它对我不起作用,我也不知道我在这里做错了什么!

控制器

$scope.products = [];

// $q.all is used because i've some other data sources too
$scope.query = function (term) {
    $q.all([
        DataService.autocomplete.products(term)

    ]).then(function (results) {
        $scope.products = results[0].data.content;
    });
};

的DataService

// dataservice return value
return {
    autocomplete: {
        products: function (term) {
            // _makeRequest is a wrapper for a $http call
            return _makeRequest('autocomplete/products', term);
        }
    }
}

单元测试

describe('[Autocomplete] AutocompleteCtrl', function () {
    var $scope, DataService;

    beforeEach(module('Autocompleter'));

    beforeEach(inject(function ($rootScope, $controller, _$q_, _DataService_) {

        var deferred = _$q_.defer();
        $scope = $rootScope.$new();
        DataService = _DataService_;

        $controller('AutocompleteCtrl', {$scope: $scope});
        deferred.resolve(['resolveData']);
        spyOn(DataService.autocomplete, 'products').and.returnValue(deferred.promise);
    }));


    describe('Query', function () {

        it('should resolve promise', function () {
            $scope.query('term');
            $scope.$apply();
            expect($scope.products).toBe(['resolveData']);
        });

    });
});

试验结果

TypeError: 'undefined' is not an object (evaluating 'results[0].data.content')

2 个答案:

答案 0 :(得分:1)

您希望.data.content的结果为DataService.autocomplete.products()

因此,您应该从以下位置更改模拟数据:

deferred.resolve(['resolveData']);

改为:

deferred.resolve({ data: { content: ['resolveData'] } });

希望这有帮助。

答案 1 :(得分:1)

您的控制器期望DataService.autocomplete.products()函数返回一个promise,并期望使用具有data属性的对象解析此promise,因为您正在执行:

results[0].data.content

在测试中,您使用以下值解决假承诺:

['resolveData']

所以,而不是让对象看起来像

{
    data: 
    {
        content: 'someValue'
    }
}

控制器收到['resolveData']

显然,访问['resolveData']的数据属性会导致未定义的值。