Angularjs单元测试解决承诺 [英] Angularjs unit testing resolving promises

查看:118
本文介绍了Angularjs单元测试解决承诺的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我可能这样做不对,但我无法弄清楚如何解决它。

I'm probably doing this wrong but I can't figure out how to fix it.

我要测试使用的资源(ngResource)控制器,我想用一个间谍作为测试双重的资源,因此不会实际做HTTP调用。在code下面我只是想测试在控制器中的搜索功能。

I want to test a controller that uses a resource (ngResource) and I want to use a Spy as a test double for the resource so it doesn't actually do the http call. In the code below I just want to test the search function in the controller.

控制器:

controllers = angular.module('app.controllers');
controllers.controller('landingCtrl', ['$scope', '$q', 'categoryResource', function ($scope, $q, categoryResource) {

    $scope.search = function (text) {
        console.log('searching for: ' + text);
        var deferred = $q.defer();
        categoryResource.query({ searchTerm: text }, function (result) {
            if (result.length == 0) {
                deferred.resolve(['No results found']);
            } else {
                deferred.resolve(result);
            }
        });
        return deferred.promise;
    }
}]);

服务:

var services = angular.module('app.services');    
services.factory('categoryResource', ['$resource', function ($resource) {
    var resource = $resource('/api/category');    
    return resource;
}]);

规格为landingCtrl:

Spec for landingCtrl:

describe('Controller: landingCtrl ', function () {

    var $q,
        $rootScope,
        $scope;

    beforeEach(module('ngResource'));
    beforeEach(module('app.services'));
    beforeEach(module('app.controllers'));

    beforeEach(inject(function (_$rootScope_, _$q_) {
        $q = _$q_;
        $rootScope = _$rootScope_;
    }));

    // mock any depencencies, like scope. $resource or $http
    beforeEach(inject(function ($controller, $injector, categoryResource) {
        $scope = $rootScope.$new();

        spyOn(categoryResource, 'query').andCallFake(function (searchText) {
            console.log('query fake being called');
            var deferred = $q.defer();
            deferred.resolve(['Test', 'Testing', 'Protester']);
            return deferred.promise;
        });

        landingCtrl = $controller('landingCtrl', {
            '$scope': $scope,
            '$q': $q,
            'categoryResource': categoryResource
        });
    }));

    afterEach(inject(function ($rootScope) {
        $rootScope.$apply();
    }));

    it('should return words with "test" in them"', function () {
        $scope.search('test').then(function (results) {
            console.log(results);
            expect(results).toContain('Test');
        });
        $scope.$apply();
    });
});

测试执行没有错误,但它传递而没有解决的承诺使,那么功能里面我的code从不被调用。我在做什么错了?

The test executes without errors but it passes without ever resolving the promise so my code inside the "then" function never gets called. What am I doing wrong?

我创建的上方,应该测试失败一个plunker:

I've created a plunker with the above and a test that should fail:

http://plnkr.co/edit/adE6fTajgbDoM33rtbZS?p=$p$ PVIEW

推荐答案

您规格嘲笑 categoryResource.query()所以它返回一个承诺,但你的控制器ISN ŧ期待的。它调用查询()并传递一个回调,而回调中它做它的事。换句话说,你的天赋是不是测试你的控制器做什么。

Your spec is mocking categoryResource.query() so it returns a promise, but your controller isn't expecting that. It calls query() and passes a callback, and within that callback it does its thing. In other words, your spec isn't testing what your controller does.

这是你的固定规格:

spyOn(categoryResource, 'query').andCallFake(function (searchText, callback) {
    console.log('query fake being called');
    callback(['Test', 'Testing', 'Protester']);
});

...

it('should return words with "test" in them"', function () {
    var results;

    $scope.search('test').then(function (_results_) {
        console.log(results);
        results = _results_;
    });
    $scope.$apply();

    expect(results).toContain('Test');
});

工作Plunker

请注意,我提出了则()回调外的期望,所以你的测试中断,如果承诺没有得到解决。

Notice that I have moved the expectation outside the then() callback, so your test breaks if the promise isn't resolved.

这篇关于Angularjs单元测试解决承诺的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆