你如何模拟 angularjs $resource 工厂

2024-02-04

我有一个资源工厂

angular.module('mean.clusters').factory('Clusters', ['$resource',
  function($resource) {
    return $resource('clusters/:clusterId/:action', {
        clusterId: '@_id'
    }, {
        update: {method: 'PUT'},
        status: {method: 'GET', params: {action:'status'}}
    });
}]);

和一个控制器

angular.module('mean.clusters').controller('ClustersController', ['$scope',
  '$location', 'Clusters',
    function ($scope, $location, Clusters) {
        $scope.create = function () {
            var cluster = new Clusters();

            cluster.$save(function (response) {
                $location.path('clusters/' + response._id);
            });
        };

        $scope.update = function () {
            var cluster = $scope.cluster;

            cluster.$update(function () {
                $location.path('clusters/' + cluster._id);
            });
        };


        $scope.find = function () {
            Clusters.query(function (clusters) {
                $scope.clusters = clusters;

            });
        };
}]);

我正在编写我的单元测试,我发现的每个示例都使用某种形式$httpBackend.expect模拟来自服务器的响应,我可以很好地做到这一点。

我的问题是,当对我的控制器功能进行单元测试时,我想模拟 Clusters 对象。如果我正在使用$httpBackend.expect,并且我在我的工厂中引入了一个错误,我的控制器中的每个单元测试都会失败。

我想进行测试$scope.create仅测试$scope.create也不是我的工厂代码。

我尝试在以下位置添加提供商beforeEach(module('mean', function ($provide) {我测试的一部分,但我似乎无法做对。

我也尝试过

clusterSpy = function (properties){
    for(var k in properties)
        this[k]=properties[k];
};

clusterSpy.$save = jasmine.createSpy().and.callFake(function (cb) {
    cb({_id: '1'});
});

和设置Clusters = clusterSpy; in the before(inject但在创建函数中,间谍迷失了

错误:预期有间谍,但得到了功能。

我已经能够得到一个间谍对象来为cluster.$update键入调用,但随后失败var cluster = new Clusters();出现“不是函数”错误。

我可以创建一个适用于的函数var cluster = new Clusters();但随后失败了cluster.$update类型调用。

我可能在这里混合了术语,但是,有没有一种正确的方法可以用函数上的间谍来模拟集群,或者有一个很好的理由去使用$httpBackend.expect?


看起来我有几次很接近,但我想我现在已经弄清楚了。

解决方案是上面的“我也尝试过”部分,但我没有从函数返回间谍对象。

这有效,它可以放置在beforeEach(module( or beforeEach(inject部分

第 1 步:使用您想要测试的任何函数创建间谍对象,并将其分配给您的测试可访问的变量。

第 2 步:创建一个返回间谍对象的函数。

步骤3:将spy对象的属性复制到新函数中。

clusterSpy = jasmine.createSpyObj('Clusters', ['$save', 'update', 'status']);

clusterSpyFunc = function () {
    return clusterSpy
};

for(var k in clusterSpy){
    clusterSpyFunc[k]=clusterSpy[k];
}

第四步:将其添加到$controller中beforeEach(inject部分。

ClustersController = $controller('ClustersController', {
    $scope: scope,
    Clusters: clusterSpyFunc
});

在您的测试中,您仍然可以使用以下方法向方法添加功能

clusterSpy.$save.and.callFake(function (cb) {
    cb({_id: '1'});
});

然后检查间谍值

expect(clusterSpy.$save).toHaveBeenCalled();

这解决了两个问题new Clusters() and Clusters.query不是一个函数。现在我可以对我的控制器进行单元测试,而无需依赖资源工厂。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

你如何模拟 angularjs $resource 工厂 的相关文章

随机推荐