【问题标题】:Dynamically override angular service?动态覆盖角度服务?
【发布时间】:2015-01-19 20:04:00
【问题描述】:

用例:

我正在使用 Geb/Selenium 编写系统测试(所以在角度之外)。 我想装饰 $http 以在运行时记录所有请求/响应。

关键是:无需接触源代码

在你急于回答“使用$provide#decorator”之前,例如,

http://blog.xebia.com/2014/08/08/extending-angularjs-services-with-the-decorate-method/

该解决方案对于这个用例意味着在生产代码中添加一个测试钩子......这通常是一件坏事,如果可能的话,我想避免。

更新:Geb 允许您在浏览器窗口中运行 Javascript。所以只是为了它,我运行了教程代码来装饰 $http。不幸的是,它不起作用,因为显然您无法在加载后重新配置应用程序。但即使它确实有效,这也带来了另一个有趣的点——我需要在任何模块有机会使用它之前覆盖 $http

【问题讨论】:

  • 我宁愿为此使用拦截器,但它们也必须在运行时之前进行配置。不过,您可以滥用转换器,因为它们可以在运行时添加。
  • re:在任何模块有机会使用它之前进行装饰,这就是配置块的想法,它们将在应用程序代码执行之前在应用程序引导期间执行

标签: angularjs decorator angular-decorator


【解决方案1】:

由于装饰 $http 服务将是这样做的最干净的方式,您可以通过使用 ng-constants 和 gulp/grunt 之类的东西只为“测试”环境添加装饰代码来避免污染生产代码。

在此处查看相关问答:How do I configure different environments in Angular.js?

如果您倾向于在运行时更改此设置(运行时发生在测试环境中),您可能需要“更接近金属”并处理 XMLHttpRequests:Add a "hook" to all AJAX requests on a page

【讨论】:

  • 是的,我们使用 grunt。不,我可能不会使用 ng-constants。但主要想法对我们有用:创建一个新的 grunt 任务,用测试版本覆盖应用程序配置文件(我们的应用程序中的 app.js)。唯一的缺点是你现在有两个版本的 app.js 需要维护,所以我们可能仍然需要接触 prod 代码。但是使用这种技术,prod 中的测试钩子是最小的。
  • 出于好奇,为什么不能使用 ng-constants?它所做的只是生成一组可以注入到您的应用程序中的值/常量(在构建时)?
  • 因为要求不接触生产代码。但是在意识到我们必须维护两个版本的 app.js 之后,添加简单的测试钩子看起来并没有那么糟糕
  • @UAvalos 您不需要“触摸”生产代码。使用 gulp/grunt 您可以检测角度服务/常量/等,这些服务/常量/等会在为测试环境构建时执行某些操作(装饰 $log),或者在为生产环境构建时执行无操作 - 这就是该策略的美妙之处我链接到
猜你喜欢
  • 2019-03-20
  • 2023-03-16
  • 2016-10-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-11-01
  • 2018-12-04
  • 2018-08-18
相关资源
最近更新 更多