【问题标题】:angular ngMock $httpBackend: split mocks into multiple filesangular ngMock $httpBackend:将模拟拆分为多个文件
【发布时间】:2015-05-09 08:44:19
【问题描述】:

我正在开发一个大型 Angular 应用程序,它需要在浏览器中模拟整个 API(也称为 无后端开发)。我的应用程序中有很多不同的部分和视图,每个部分都有自己的模拟定义。

我知道我可以使用ngMock 模块的$httpBackend 服务来模拟AJAX 调用。这就是我想要的。我找到了working snippet at jsfiddle。

但我缺少的是如何将其拆分为多个文件?正如我所说,我的应用程序将有数百个页面,甚至可能有更多的 RESTful 资源,我不能简单地将其放入一个源文件中。这作为架构问题:将数千个 whenGET 和 whenPOST 调用分成不同文件以简单地模拟相同 API 的最佳方法是什么(即有效、可扩展且易于维护)? 如何在项目文件结构方面分离 mocks?应用程序中的每个模块是否应该有一个单独的.run() 方法?我可以从 JSON 文件加载模拟吗?

我将不胜感激解释和演示

为了让回答更容易,下面是小提琴的相关部分:

myApp.run(function ($httpBackend) {
    var phones = [{name: 'phone1'}, {name: 'phone2'}];

    $httpBackend.whenPOST('/phones').respond(function (method, url, data, headers) {
        console.log('Received these data:', method, url, data, headers);
        phones.push(angular.fromJson(data));
        return [200, {}, {}];
    });

    $httpBackend.whenGET('/phones').respond(function (method, url, data) {
        console.log("Getting phones");
        return [200, phones, {}];
    });

    $httpBackend.whenGET(/\.html$/).passThrough();
});

【问题讨论】:

  • 你最后采用了什么方法?我目前处于同样的情况,想知道最好的方法。 @杜辛
  • @Jagrut 或多或少地回答您的问题,我所做的是使用 browserify 进行捆绑。您的源代码中存在数百个调用问题 - 因此您希望将源代码拆分为多个文件。但是您可以使用 concat/browserify/webpack/(它们的组合)来生成单个目标文件(将从index.html 使用)。因此,您可以从源代码中的清晰和可扩展层次结构中受益AND 在构建中拥有一个大的mock.js 输出文件(dist、输出,无论您如何称呼它)。您还可以包含/排除 mock.js 以打开/关闭模拟!希望有帮助:)
  • 实际上,我的团队负责人希望我有一个单独的文件,其中包含所有 $httpBackend 调用,并且我在所有单元测试中都包含该文件。那可能吗?抱歉回复晚了。
  • @Jagrut 当然是。您将在 SOURCE 中为单独的请求/响应保留单独的文件。但为了测试它或基于模拟运行应用程序,请使用 browserify、grunt、gulp 或其他任何东西来生成一个文件。我也做同样的事情。所以你们俩都会满意的:)
  • 我所做的是创建了一个包含所有 $httpBackend 调用的 JSON 文件,然后使用 karma-json-fixtures-preprocessor 能够将该文件包含在我的所有测试用例中。比起执行部分,我们更关心的是代码的维护和重写。我不确定这是否是一个好习惯。你怎么看?

标签: javascript angularjs file mocking ngmock


【解决方案1】:

你可以这样使用:

XXXModule.factory('MockedDataProvider', () ->
  getData: (url) ->
    request = new XMLHttpRequest();
    request.open('GET', url, false)
    request.send(null)
    request.response
)
.run([
  '$httpBackend',
  'MockedDataProvider'
  ($httpBackend, MockedDataProvider) ->
    $httpBackend.whenGET(/i18n/).passThrough()
    $httpBackend.whenGET('/api/xxx/yyy').respond(
      (method, url, data) ->
        data = MockedDataProvider.getData('xxx/mocked.json')
        [200, data]
 )
])

你可以将你的模拟分成单独的文件夹/模块等......它应该工作得很好:)

附言。代码在咖啡脚本中;)

【讨论】:

【解决方案2】:

我遇到过类似的问题,这是我的解决方案。

请注意,我使用的是generator-cg-angular,并且文件结构是从那里继承的。

index.html ..................... main HTML file
app.js ......................... angular module initialization and route setup
httpBackendStub.js ............. backend stub module
/service ....................... angular services folder
    dimension.js ............... example service
    dimension-spec.js .......... example service unit test
    dimension-stub.js .......... example backend stub with routes and data

有data-concat="false" 属性,这意味着所有后端存根都将在构建时被删除。

index.html

<!-- Bower components and angular app scripts included here -->
...
<!-- Backend stubbing -->
<script src="bower_components/angular-mocks/angular-mocks.js" data-concat="false"></script>
<script src="httpBackendStub.js"        data-concat="false"></script>
<script src="service/dimension-stub.js" data-concat="false"></script>
...
<!-- Initial HTML markdown -->

httpBackendStub.js

angular.module('app')
    .config(function($provide) {
        $provide.decorator('$httpBackend', angular.mock.e2e.$httpBackendDecorator);
    })
    .run(function ($httpBackend) {
        // pass templates
        $httpBackend.whenGET(/partial\/.*/).passThrough();
    });

服务/维度-stub.js

angular.module('app').run(function ($httpBackend) {

    $httpBackend.whenGET('api/dimensions').respond([
        {
            name: 'Medium',
            ...
        },
        ...
    ]);

});

【讨论】:

  • 这不是非常可扩展的,因为:[1] 您将每个 js 文件添加到 html 中。在一个大项目中,这可能会变成数百或数千,更不用说如果有人犯了错误,要调试这么多是非常困难的。此外,您的数据 (dimension-stub) 是在 js 和 角度结构中硬编码的。它不能被其他任何东西重用(例如 grunt 或 gulp)。
  • 是的,我同意你的论点。我曾考虑过使用动态加载的 JSON,但对于这个特定项目来说并非如此。你能描述一下你目前的安装吗?
  • 我正在存储 JSON 文件,使我能够在自定义的 grunt 任务中使用它们。它们是 browserify 的 required 并与 ngMock 文件一起创建一个包。总体而言,构建了一个很棒的mock.js。它要么作为 JS 标记添加到 index.html(在模拟模式下),要么被忽略(然后应用程序将请求发送到真实 API)。我得出的结论是,角度架构非常不灵活/贪婪,并且只允许角度相似的组件相互配合。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-08-24
  • 2011-12-25
  • 1970-01-01
  • 2017-01-02
  • 2010-10-10
相关资源
最近更新 更多