AngularJS - 将函数传递给spyOn

时间:2015-12-08 15:39:32

标签: javascript angularjs unit-testing

所以我有这个简单的,淡化的应用程序返回NATO字母表,然后使用模拟和承诺对其进行单元测试。

HERE'S A LIVE DEMO

我试图从spyOn .service() MainModel尝试natoAlphabet。在控制器中,我有一个名为getNato的延迟承诺,可以在页面上成功显示。

首先,我引用了MainController中的MainController.getNato,但我从未将MainModel.getNato设置为MainController

所以我添加了this.getNato = MainModel.getNato;

Expected spy getNato to have been called.

我收到错误:console log

但是,在mockMainCtrl中,如果您执行beforeEach的控制台输出,控制器在顶部附近的Object {name: "Hello World!", getNato: Promise}内被模拟,则会得到it()

然后在第一个Object {name: "Hello World!"}测试的下方,输出为Object {name: "Hello World!"} getNato: Promise name: "Hello world!"; __proto__: Object 但是,如果你展开那个,你会得到:

beforeEach

而在getNato内的那个,你有Expected spy getNato to have been called.

我的错误

我的错误发生在Jasmine测试运行时,我从{strong> theSpec.js 上的expect(mockMainCtrl.getNato).toHaveBeenCalled();行获得describe('Controller: MainCtrl', function() { beforeEach(module('app')); var $scope, $q, mockMainCtrl, $controller, scope, deferred; beforeEach(inject(function($controller, _$rootScope_, _$q_, MainModel) { $q = _$q_; $scope = _$rootScope_.$new(); deferred = _$q_.defer(); mockMainCtrl = $controller('MainCtrl', { $scope: $scope, MainModel: MainModel }); console.log(mockMainCtrl); })); it('spied and have been called', function() { spyOn(mockMainCtrl, 'getNato'); console.log(mockMainCtrl); expect(mockMainCtrl.getNato).toHaveBeenCalled(); }); it('Name from service, instantiated from controller, to be mocked correctly', inject(function() { expect(mockMainCtrl.name) .toEqual("Hello World!"); })); it('Get [getNato] mocked deferred promise', function(mainCtrl) { deferred.resolve([{ id: 1 }, { id: 2 }]); $scope.$apply(); expect($scope.results).not.toBe(undefined); expect($scope.results).toEqual(['Alpha', 'Bravo', 'Charlie', 'Delta', 'Echo', 'Foxtrot', 'Golf', 'Hotel', 'India']); expect($scope.error).toBe(undefined); }); });

那么我做错了什么?

我认为 app.js 没有任何问题,因为该网页可以成功阅读承诺。

附录:

theSpec.js

var app = angular.module('app', []);

app.service('MainModel', function($q) {
  this.name = "Hello World!";

  var getNato = function() {
    var deferred = $q.defer();
    var theNatoAlphabet = ['Alpha', 'Bravo', 'Charlie', 'Delta', 'Echo', 'Foxtrot', 'Golf', 'Hotel', 'India'];
    deferred.resolve(theNatoAlphabet);
    return deferred.promise;
  };

  this.getNato = getNato();
});

app.controller('MainCtrl', function($scope, MainModel) {
  this.name = MainModel.name;

  var self = this;

  MainModel.getNato.then(function(data) {
    self.natoAlphabet = data;
    $scope.results = data;
  }).catch(function() {
    $scope.error = 'There has been an error!';
  });

  this.getNato = MainModel.getNato;


});

app.js

{{1}}

1 个答案:

答案 0 :(得分:1)

看看 - http://plnkr.co/edit/57ZA8BXscmdY6oDX5IOA?p=preview

你想要'spyOn'依赖,即'MainModel',并在'$ controller'构造之前执行,因为'promise'在构造控制器时得到解决。希望这会有所帮助。

像 -

  beforeEach(inject(function($controller, _$rootScope_, _MainModel_) {
    scope = _$rootScope_.$new();
    MainModel = _MainModel_;
    spyOn(MainModel, 'getNato').andCallThrough();
    mockMainCtrl = $controller('MainCtrl', {
      $scope: scope
    });
  }));

  it('spied and have been called', function() {
    expect(MainModel.getNato).toHaveBeenCalled();
  });