如何在 AngularJS 单元测试中模拟 Promise 的结果?

2024-01-22

My CompanyService is:

angular.module('mean').service('CompanyService', ['$http', '$rootScope', '$q', function($http, $rootScope, $q) {
  var company = this;
  var initializedDeferred = $q.defer();

  company.company_data = {}
  company.initialized = initializedDeferred.promise;

  company.getCompany = function() {
    return company.company_data;
  }

  company.get = function (company_id) {
    return $http({
      url: '/api/v1/company/' + company_id,
      method: 'GET',
      headers: {
        api_key: $rootScope.api_key
      }
    }).success(function(response) {
      if(response.status === 'ok') {
        company.company_data = response.company;
        initializedDeferred.resolve();
      } else {
        alert('TBD: Need fail case');
      }
    });
  };
}]);

我的控制器是:

angular.module('mean').controller('LocationController', ['$scope', '$location', '$rootScope', 'LocationService', 'UserService', 'CompanyService', '$modal', '$routeParams', function ($scope, $location, $rootScope, LocationService, UserService, CompanyService, $modal, $routeParams) {
  $rootScope.menuItem = 'locations';
  $scope.contentTemplate = '/views/location/index.html';
  $scope.locations = [];
  $scope.current_location = null;
  $scope.newLocation = {};
  $scope.location_parent_id = $routeParams.location_parent_id;

  $scope.index = function() {
    CompanyService.initialized.then(function() {
      $scope.test = 'a';
      var company_id = CompanyService.getCompany()._id;
      LocationService.list(company_id, $routeParams.location_parent_id).then(function(response) {
        if(response.data.status === 'ok') {
          $scope.locations = response.data.locations;
          $scope.current_location = response.data.location || null;
        }
      });
    });
  }

  $scope.addLocationModal = function() {
    $scope.location_types = ['warehouse', 'section', 'row', 'shelf', 'bin'];
    $modal({
      scope: $scope,
      template: '/views/location/addLocationModal.html',
      show: true,
      animation: 'am-fade-and-scale'
    });
  }

  $scope.createLocation = function() {
    $scope.newLocation.company_id = CompanyService.getCompany()._id;
    LocationService.create($scope.newLocation).then(function(response) {
      if(response.data.status === 'ok') {
        $scope.$hide();
      } else {
        alert('TBD');
      }
    });
  }

}]);

我的测试是:

(function() {
  describe('LocationController', function() {
    var $scope, $location, $rootScope, $modal, deferred, CompanyService, createController;

    beforeEach(module('mean'));

    beforeEach(inject(function($injector) {
      $location = $injector.get('$location');
      $rootScope = $injector.get('$rootScope');
      $modal = $injector.get('$modal');
      $scope = $rootScope.$new();

      var $controller = $injector.get('$controller');

      var $q = $injector.get('$q');

      var params = {
        '$scope': $scope,
        CompanyService: jasmine.createSpyObj('CompanyService', ['initialized'])
      }

      params.CompanyService.initialized.andCallFake(function () {
        deferred = $q.defer();
        return deferred.promise;
      });


      createController = function() {
        return $controller('LocationController', params);
      };
    }));

    it('should instantiate initial variables at the top level', function() {
      var controller = createController();

      $location.path('/company/locations');
      expect($location.path()).toBe('/company/locations');
      expect($rootScope.menuItem).toBe('locations');
      expect($scope.contentTemplate).toBe('/views/location/index.html');
      expect($scope.locations.length).toEqual(0);
      expect($scope.current_location).toBeNull();
      expect($scope.newLocation).toBeDefined();
      expect($scope.location_parent_id).not.toBeDefined();
    });

    it('should list all locations for this company', function() {
      var controller = createController();
      deferred.resolve();
      $scope.index();

      expect($scope.test).toBe('a');
    });
  });
})();

但是,resolve不工作。我收到此错误:TypeError: 'undefined' is not an object (evaluating 'deferred.resolve')

有什么帮助吗?


在您的测试中,您使用 fake 创建延迟对象CompanyService.initialized功能。然而这个函数只有当你调用时才会被调用$scope.index();,这是在你之后执行的deferred.resolve();线。以下应该有效:

it('should list all locations for this company', function() {
  var controller = createController();
  $scope.index();   // Should in turn call the fake CompanyService.initialized function that creates deferred
  deferred.resolve();
  $scope.$apply();  // Fire $digest cycle to dispatch promises.

  expect($scope.test).toBe('a');
});

Update

Jasmine 不支持监视非函数的属性。所以你的间谍设置​​是无效的CompanyService.initialized是一个对象而不是函数,所以你的andCallFake不会工作。解决方法是在你的程序中引入一个 getter 函数CompanyServicee.g:

company.isInitialized(){ return company.initialized; }

然后在你的控制器内部使用这个 getter 函数:

$scope.index = function() {
  CompanyService.isInitialized().then(function() {
    $scope.test = 'a';
    // Removed for brevity
  });
}

最后更新您的测试代码初始化:

var params = {
  '$scope': $scope,
  CompanyService: jasmine.createSpyObj('CompanyService', ['isInitialized'])
}
params.CompanyService.isInitialized.andCallFake(function () {
  deferred = $q.defer();
  return deferred.promise;
});
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在 AngularJS 单元测试中模拟 Promise 的结果? 的相关文章

  • 尝试制作Linux终端但失败

    这可能是一个愚蠢的问题 可能很容易找到 但我对这一切都很陌生 我似乎找不到我要找的东西 或者至少我不知道我需要寻找什么 所以我在这里 所以我想做的是创建一种 Linux 终端 这就是我到目前为止所得到的 我所坚持的是实际输入文本部分 我一直
  • { ...obj1, obj2 } 到底做什么[重复]

    这个问题在这里已经有答案了 假设我们有两个对象 const state fishes some obj data animals some obj data const animals some NEW data 在Vuex中有一个方法re
  • 如何使用 jQuery 添加/附加到外部 JSON 文件

    我有一个 json 文件 我想构建一个表单 允许我在文件中添加 编辑元素 是否有 jQuery 函数 方法允许我在外部 json 文件中发布和追加元素 不确定这是否有帮助 但当前的 json 结构如下 cast director genre
  • 隐藏加载失败的图片

    我有一个 Android 应用程序 它生成一些在本地 Webkit 视图中呈现的 HTML HTML 生成的细节实际上并不那么重要 除了 大部分来自一个地方 我无法改变它 HTML 周围的模板 包括页眉 页脚 HEAD 等 CSS 和 Ja
  • 如何通过两个输入文本字段组合表中的搜索?

    我的桌子看起来像这样 table tr td Apple td td Green td tr tr td Grapes td td Green td tr tr td Orange td td Orange td tr table 搜索的j
  • JavaScript 事件循环:队列、消息队列、事件队列

    阅读了大量 JavaScript 事件循环教程 我看到了不同的术语来标识当调用堆栈为空时准备由事件循环获取的队列存储消息 Queue 消息队列 事件队列 我找不到规范术语来识别这一点 甚至 MDN 似乎也对此感到困惑事件循环页面 https
  • Javascript:一般访问函数参数

    这是我所拥有的 var log function arg1 arg2 console log inside arg1 arg2 var wrap function fn return function args console log be
  • 浏览器中的javascript:异步任务执行模型

    我正在尝试集中注意力并了解 javascript 异步在单线程浏览器环境中的工作原理 作为异步 我们可以同时处理计时器和 xhr 请求 现在假设我有类似下面的东西 function doStuff for var i 0 i lt 1000
  • 如何从 HTML 图表中删除网址 [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我正在 HTML 中创建一个图表 我正在使用 API amCharts 但问题是它在图表中显示文本 amchart 我怎样才能删除该文本
  • Mustache.js 只允许换行,转义其他 HTML

    我正在根据用户输入创建评论 并在用户单击 提交 后使用 Mustache js 渲染它们 我意识到我可以替换用户输入换行符 n with br 呈现为 HTML 中断 例如 myString replace n g br 我意识到我可以使用
  • 如何将多种语言设置放入单个 .clang-format 文件中

    我想为 java javascript 和 c 创建一个 clang 格式 我知道如何转储单一语言的示例配置 但不知道如何合并这 3 个配置文件 有关如何将多种语言配置放入单个文件中的示例 BasedOnStyle LLVM IndentW
  • 从 Web 浏览器控件读取 Javascript 变量

    我正在尝试读取从表单上的 WebBrowser 控件加载和调用的 Javascript 变量的值 Example index html 引用名为 test js 的 javascript 在 test js 上 创建并填充了几个变量 然后i
  • Svg 点击事件无法正常工作

    我试图让我的 SVG 看起来像一个 饼形 看起来一切都很好 此外 我希望它们每个都有不同的点击事件 function one alert 1 function two alert 2 function three alert 3 funct
  • Select2 触发器(“更改”)创建无限循环

    假设页面上有两个 select2 元素 都使用 onChange 为了以编程方式在一个 select2 元素中设置一个值 您可以使用 id1 val xyz trigger change 如果您在这两个元素之一中进行选择时想要将另一个元素重
  • 如何模拟类路径上属性文件的存在?

    这肯定是一个常见问题 我有一个像这样的属性文件my settings properties由应用程序类读取 当我编写测试类时 它需要测试可能存在的不同场景my settings properties为了确保最大的代码覆盖率 例如空属性文件
  • 有没有办法通过 JavaScript 检测我是否处于 Selenium Webdriver 页面中?

    我想禁止初始化TinyMCE https www tiny cloud 在我的测试中 如果 JavaScript 可以检测到我正在 Selenium 自动化页面中运行 则可以轻松完成此操作 那么 是否有一些 JavaScript 代码可以用
  • 如何触发UI-Router View Load事件?

    第一次测试 ui router 但目前测试事件 我似乎无法理解如何触发 viewContentLoaded 或 Loading 虽然 我已经有 stageChangeSuccess 等工作了 我只是把一切都推到了http punkbit c
  • 函数声明可以出现在 JavaScript 的语句内部吗?

    请考虑将官方 ECMAScript 规范作为您答案的来源 而不是特定浏览器供应商发布的文档 我知道 Mozilla 用 函数语句 扩展了它的 JavaScript 实现 因此 根据 ECMAScript 规范 因此 其中定义的语法产生式 这
  • 静态资源和非静态资源有什么区别?

    我主要是一名前端开发人员 设计师 但最近我一直在探索端到端解决方案 昨天 我使用平均堆栈完成了一个 TODO 应用程序 并想开始探索我的 VPS 的部署选项 话虽这么说 有人建议我使用 nginx 作为反向代理来提供静态资源 不幸的是 我陷
  • Django pbkdf2_sha256 JS 实现

    我有一个来自 django 的数据库 我想从 Node js 中使用它 我有一个任务 验证用户身份 从数据库可知 算法 pbkdf2 sha256 salt 10000 次迭代和 base64 编码的哈希值 我必须在 JS 中执行哪些步骤才

随机推荐

  • Elasticsearch 集群“master_not_discovered_exception”

    我已经安装了elasticsearch 2 2 3并在2个节点的集群中进行了配置 节点 1 elasticsearch yml cluster name my cluster node name node1 bootstrap mlocka
  • 语音识别在 Unity Hololens 项目中不起作用

    我正在尝试在 Hololens 中创建自己的具有语音识别功能的 Unity 项目 我复制粘贴了来自的说明tutorial https developer microsoft com en us windows holographic hol
  • 查明某个类型是否实现了通用接口

    假设我有一个类型 MyType 我想做以下事情 查明对于某些 T MyType 是否实现了 IList 接口 如果 1 的答案是肯定的 请找出 T 是什么 似乎执行此操作的方法是 GetInterface 但它只能让您按特定名称进行搜索 有
  • Realm android 中的更新语句

    我应该如何在android中使用领域数据库更新已经存在的值 我一直在尝试更新它 但它只是作为新值添加而不覆盖它 更新现有对象及其领域数据库中所有字段的另一种方法是使用以下方法realm copyToRealmOrUpdate Object
  • PHP MYSQL 以阿拉伯语插入数据

    我正在尝试使用 PHP 和 HTML 表单将一些阿拉伯语言数据插入到 MySQL 中 当我将数据插入MYSQL表时 表字段将数据表示为 但是当我使用 PHP 访问相同的数据并将其显示在我的网页中时 它显示了正确的数据 我在用 http eq
  • 取消的任务也显示为已完成

    我正在尝试使用异步等待和取消来对此事有更多的了解 为此 我制作了以下控制台应用程序 using System using System Threading using System Threading Tasks namespace Asy
  • JavaScript 中的点运算符

    我认为点运算符只能应用于对象来访问其属性 IE 例如 var o prop property alert o prop property 当JS执行时alert o prop 第一个包含引用的对象o将进一步发现将找到包含引用的属性o pro
  • 按钮突出显示状态的延迟

    我在两种完全不同的情况下遇到了这个问题 这使得它非常奇怪 情况 一个 UIButton 作为另一个 UIView 的子视图 情况 UIBarButtonItem 在 UIToolBar 中 在这两种情况下 按钮仅在稍有延迟 大约 0 5 1
  • 支持多个版本的 Excel 以从 Access 应用程序实现自动化

    我有一个 Access 应用程序 是在多用户环境中的 Access 2013 中开发的 它使用 Excel 自动化来导出和格式化 Excel 文件 正常的 Office Excel 2013 15 0 参考已完成 并且在 Office 20
  • 随机慢速 Rack::MethodOverride#call on Rails app on Heroku

    环境 红宝石 2 1 2 轨道 4 1 4 Heroku 在 Heroku 上托管的 Rails 应用程序中 有时请求需要很长时间才能执行 它只有 1 的次数或更少 但我们无法弄清楚它发生了什么 我们安装了 newrelic 代理 它说它不
  • 如何将 Spring-Boot-Webflux 应用程序部署到 Tomcat 独立服务器?

    一个普通的 spring web 应用程序可以部署到tomcat独立为war文件如下 SpringBootApplication public class MyApplication extends SpringBootServletIni
  • Symfony 渲染控制器异常模板(“”)

    我试图在树枝内渲染一个控制器 我遵循文档 嵌入其他控制器 我经常使用 render controller 方法获得豁免 渲染模板期间抛出异常 在我的 template html twig 中 render controller MyBund
  • 确定元素在文档上的绝对位置

    我需要确定 HTML 元素的确切屏幕坐标 相对于文档 我已经有执行此操作的代码 将每个父对象的 clientWidth 和 clientHeight 相加到根 但当 jQuery 的滚动效果开始工作时似乎无效 事实上 我需要检测位置的元素是
  • 在 mongodb 的一次更新调用中推送到两个单独的数组

    我正在尝试更新以通过一次更新调用来更新文档中的两个单独的数组 有没有办法做到这一点 例如 如果我有一个类似的文档 id 1 array1 1 array2 4 现在我正在这样做 db collection update id 1 push
  • Oracle SQL技术避免填充trans log

    Oracle 编程新手 来自 Sybase 和 MS SQL Server 避免用大量更新填充事务日志的 Oracle 方式 是什么 在我的具体情况下 我正在更新可能非常大量的行 这是我的方法 UPDATE my table SET a c
  • Django 表已经存在

    这是我的 Django 迁移文件 当我跑步时 python manage py makemigrations migrate 我收到这个错误 Error django db utils OperationalError 1050 Table
  • 将非常大的 Gradle 项目与许多子项目分开的指南,以使 Gradle 构建更快,IntelliJ Gradle 刷新更快

    我有一个相当大的 git 项目 我有一个很大的单个 build gradle 定义子项目 在最初几年 没问题 在最初的几年之后 由于子项目的数量 Gradle 命令行配置步骤变得有点慢 例如 当我运行 gradle 命令时 我看到暂停 gt
  • 有没有一种使用正则表达式快速解析大文件的方法?

    问题 非常非常大的文件 我需要逐行解析以从每行获取 3 个值 一切正常 但解析整个文件需要很长时间 可以在几秒钟内完成此操作吗 通常所需时间为 1 分钟到 2 分钟 示例文件大小为 148 208KB 我使用正则表达式来解析每一行 这是我的
  • Rails 协会中未找到名为关联的可能拼写错误的问题

    这是我的控制器 post Post joins customers select customers posts find params id 我的帖子模型 belongs to customer 我的客户模型 has many posts
  • 如何在 AngularJS 单元测试中模拟 Promise 的结果?

    My CompanyService is angular module mean service CompanyService http rootScope q function http rootScope q var company t