AngularJS、间谍和解决承诺

AngularJS、间谍和解决承诺,angularjs,jasmine,Angularjs,Jasmine,我正在为控制器编写测试。一种方法调用服务中的方法,该方法使用承诺。在我的测试中,我嘲笑了服务,并且(我认为)正确地嘲笑了承诺。我一直在关注此博客条目: 以下是测试代码: describe('Controller: ResultsController', function () { 'use strict'; var ctrl; var ResultsServiceMock; var RouteServiceMock; var $scope; var

我正在为控制器编写测试。一种方法调用服务中的方法,该方法使用承诺。在我的测试中,我嘲笑了服务,并且(我认为)正确地嘲笑了承诺。我一直在关注此博客条目:

以下是测试代码:

describe('Controller: ResultsController', function () {
    'use strict';
    var ctrl;
    var ResultsServiceMock;
    var RouteServiceMock;
    var $scope;
    var mockResults;
    var mockPromise;
    var q;
    var deferred;

    beforeEach(module('waApp'));

    beforeEach(function() {
        ResultsServiceMock = {
            get: function(query) {
                deferred = q.defer();
                return deferred.promise;
            }
        };
        RouteServiceMock = {
            getParams: function() {
            }
        };
    });

    beforeEach(inject(function(
        $rootScope,
        $controller,
        $q
    ) {
        $scope =  $rootScope.$new();
        q = $q;
        ctrl = $controller('ResultsController', {
            $scope: $scope,
            results: ResultsServiceMock,
            route: RouteServiceMock
        });
    }));

    it('Should simulate requesting results from the api', function() {
        spyOn(ResultsServiceMock, 'get').andCallThrough();
        spyOn(RouteServiceMock, 'getParams').andReturn({input:'hamburger'});
        $scope.getResults({input:'hamburger'});  // TODO give params.  try query()
        deferred.resolve();
        $scope.$root.$digest();
        expect($scope.getResults).toHaveBeenCalled();
    });
});
但是,当我运行测试时,会出现以下错误:

Chrome 35.0 (Mac) Controller: ResultsController Should simulate requesting results from the api FAILED

TypeError: Cannot read property 'resolve' of undefined
    at null.<anonymous> (/Users/maryc/wa/app/results/results-controller_test.js:70:17)

Chrome 35.0 (Mac): Executed 14 of 14 (1 FAILED) (0.313 secs / 0.093 secs)
函数asyncPods、recalculate和related是ResultsController中的另外三种方法

编辑:修复了第一个错误后,我现在在运行测试时出现以下错误:

Chrome 35.0 (Mac) Controller: ResultsController Should simulate requesting results from the api FAILED
TypeError: undefined is not a function
    at Scope.$scope.getResults (/Users/maryc/wa/.tmp_test/results-controller.js:222:36)
    at null.<anonymous> (/Users/maryc/wa/app/results/results-controller_test.js:67:16)

我现在想知道问题是否在于此。get本身包含一个承诺?

根据您迄今为止提供的信息,这是我对可能导致问题的原因的猜测

$scope.getResults()
方法中,调用
ResultsService
get()
方法,因此服务的名称似乎是
ResultsService

但是在单元测试中,您将
ResultsServiceMock
作为
results
传递:

ctrl = $controller('ResultsController', {
  $scope: $scope,
  results: ResultsServiceMock,
  route: RouteServiceMock
});
它应该是
ResultsService
,而不是像这样:

ctrl = $controller('ResultsController', {
  $scope: $scope,
  ResultsService: ResultsServiceMock,
  RouteService: RouteServiceMock
});
进行此更改后,您可能会遇到其他问题,但您需要通过以下错误:

TypeError: Cannot read property 'resolve' of undefined

希望这能有所帮助。

请检查
ResultsServiceMock.get()
是否真的被调用。因此,似乎ResultsServiceMock.get()实际上没有被调用,但我不知道为什么会这样。您能展示
$scope.getResults()函数的实现吗?我们可以从那里开始解决问题。当然,我会编辑问题以包含getResults()代码。您是对的,这确实解决了我最初的问题!然而,它确实导致了另一个错误,我不理解;我对问题进行了编辑,以反映新的错误。如果您能以任何方式看到这一点,我将非常感激。我认为您应该开始在DevTools中调试单元测试。您可以开始了解如何设置断点。对于第二个错误,我看不到在任何地方调用了
RouteService.getParams()
,请包括调用的代码和
RouteService.getParams()
本身。因此,我已经解决了出现的大多数错误,这些错误最终都是愚蠢的错误。我留下了以下错误:Chrome 35.0(Mac)控制器:ResultsController应该模拟从api请求结果失败类型错误:未定义不是作用域中的函数。$Scope.getResults(/Users/maryc/wa/.tmp_test/results Controller.js:222:36)为null。(/Users/maryc/wa/app/results/results-controller_test.js:67:16)getResults中调用ResultsService.get的那一行表示我的承诺没有得到解决或$scope.getResults失败。222行的results-controller.js中有什么内容?错误表明它来自那里。
ctrl = $controller('ResultsController', {
  $scope: $scope,
  ResultsService: ResultsServiceMock,
  RouteService: RouteServiceMock
});
TypeError: Cannot read property 'resolve' of undefined