【问题标题】:Angular Jasmine spyOn query callAngular Jasmine spyOn 查询调用
【发布时间】:2013-04-23 18:24:23
【问题描述】:

我对 Angular 和 Jasmine 非常陌生,当我试图伪造服务“查询”调用时遇到问题。以下内容被“描述”包围:

var mockBackend;

beforeEach(inject(function($rootScope, $controller, AppServ) {
  // We need to setup our controllers to use fake services provided by angular-mocks
  $scope = $rootScope.$new();
  mockBackend = AppServ;

  $controller('AppInformationController', {
    $scope: $scope,
    AppServ: mockBackend
  });
}));

it("should try to call the service, but we intercept it", function() {
  spyOn(mockBackend, 'query').andReturn({'title':'Mock title'});

  $scope.serverAppNameChange();
  expect($scope.app.title).toBe("Mock title");
});

“AppServ”上方是我的服务,每当测试对该服务调用“查询”以返回一些默认信息时,我都想拦截。实际上,这只是为了了解 Jasmine 和 Angular 是如何工作的。该服务本身只保留本地副本(它基本上是一个假服务)。

这里是服务:

Services.factory("AppServ", function($http) {
  var app = {};
  var theAppOnServer = {};

  app['query'] = function() {
    return theAppOnServer;
  };

  app['save'] = function(app) {
    theAppOnServer = $.extend({}, app);
  };

  app['updateApp'] = function() {
    theAppOnServer['title'] = "Title From Server";
  };

  return app;
});

这里是控制器:

MobileIntake.controller("AppInformationController", function($scope, AppServ) {
  $scope.app = AppServ.query();

  //var AppOverviewController = function($scope) {
  $scope.appNameChange = function(oldValue, newValue, scope) {
    console.log("You've changed the app name!");
  };

  $scope.serverAppNameChange = function() {
    AppServ.updateApp();
  };
  // Set up a watcher if we want to be updated by other things (like the server)
  $scope.$watch("app.title", $scope.appNameChange);

});

有人能告诉我为什么 spyOn 似乎没有拦截服务上的“查询”函数调用吗?我已经看到了其他几个答案,他们正在使用 $http 和一些特殊的逻辑,但我只是想知道我也可以拦截非 http 函数。

【问题讨论】:

    标签: angularjs jasmine


    【解决方案1】:

    您不需要额外的 mockBackend 对象。只需监视服务本身。

    beforeEach(inject(function($rootScope, $controller) {
      // We need to setup our controllers to use fake services provided by angular-mocks
      $scope = $rootScope.$new();
    
      $controller('AppInformationController', {
        $scope: $scope
      });
    }));
    
    it("should try to call the service, but we intercept it", inject(function(AppServ) {
      spyOn(AppServ, 'query').andReturn({'title':'Mock title'});
    
      $scope.serverAppNameChange();
      expect($scope.app.title).toBe("Mock title");
    }));
    

    【讨论】:

    • 我得到“AppServ”没有定义。我的“AppInformationController”需要注入 AppServ,为了得到它,我不需要在“inject(function($rootScope,$controller, AppServ))”部分中保留它吗?
    • AppServ 未定义在哪里?您将inject 添加到您的it 对吗?在为您的测试设置控制器时,您不需要为 $controller 服务提供所有依赖项。在 Angular 的 phonecat 应用程序 (github.com/angular/angular-phonecat) 中,他们有一个注入 Phone 资源 (github.com/angular/angular-phonecat/blob/master/app/js/…) 的控制器,但在测试 (github.com/angular/angular-phonecat/blob/master/test/unit/…) 中,他们没有将其传递给 $controller。跨度>
    • 在 PhoneCat 示例中,测试使用ctrl = $controller(PhoneListCtrl, {$scope: scope}); 如您所见,“PhoneListCtrl”是全局范围内的变量,而不是像我的示例那样内置在 .controller 中。我在使用全局变量而不是 module.controller 类型表示法进行测试时有更好的经验,但它应该能够以任何一种方式进行测试。
    • 对,我的意思是您不必将依赖项传递给$controller 服务。我有一个通过module.controller 注册的控制器,带有一堆注入的依赖项,在我的测试中我只做$controller("MyController", {$scope: scope});。然后我根据需要在its 中监视服务,并且一切正常。如果您在尝试将其注入您的 IT 时收到 undefinedAppServ,这让我认为它没有正确注册。
    • 我不再使用 AngularJS,所以我无法测试它是否有效。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-10
    • 1970-01-01
    相关资源
    最近更新 更多