【问题标题】:How to mock get(id) requests如何模拟 get(id) 请求
【发布时间】:2016-04-30 13:09:18
【问题描述】:

我正在构建一个应用程序原型并尝试模拟 REST Web 服务。

这是我的代码:

var mock = angular.module('mock', ['ngMockE2E']);
mock.run(function($httpBackend){
    users = [{id:1,name:'John'},{id:2,name:'Jack'}];
    $httpBackend.whenGET('/users').respond(users);
    $httpBackend.whenGET(new RegExp('\\/users\\/[0-9]+')).respond(users[0]);
}

一切正常,我的资源 User.query() 返回所有用户,而 User.get({id:1}) 和 User.get({id:2}) 返回同一个用户(John)。

现在为了改进我的原型,我想返回合适的用户,匹配好的 id。

我在the angular documentation 中读到了我应该能够用函数替换 RegExp URI。这个想法是从 url 中提取 id 以在响应方法中使用它。 然后我尝试了这个:

$httpBackend.whenGET(new function(url){
    alert(url);
    var regexp = new RegExp('\\/users\\/([0-9]+)'); 
    id = url.match(regexp)[1];  
    return regexp.test(url);
}).respond(users[id]);

问题是 url 参数总是未定义。有什么想法可以实现我的目标吗?

【问题讨论】:

    标签: angularjs angularjs-e2e


    【解决方案1】:

    通过使用new function(url),您的应用会尝试从您的匿名函数中实例化一个新对象,并将该新对象作为$httpBackend.whenGET() 调用的第一个参数传递。
    当然,调用whenGET()的时候没有提供URL,所以一直是未定义的。

    您应该传递函数本身(而不是使用该函数实例化的对象)。例如:

    $httpBackend.whenGET(function (url) {
      ...
    }).respond(users[id]);
    

    更新:
    经过更多的挖掘,结果发现将函数作为第一个参数传递给whenGET 的选项是在1.3.0-beta.3 版本中添加的。您正在阅读的文档可能是指最新的 beta 版本,而您使用的是早期版本。
    (请注意,即使是 1.3.0-beta.1 和 2 版本也没有提供此选项。)

    不说太多细节,负责验证匹配URL的是MockHttpExpectationmatchUrl方法:

    function MockHttpExpectation(method, url, data, headers) {
      ...
      this.matchUrl = function(u) {
        if (!url) return true;
        if (angular.isFunction(url.test)) return url.test(u);
        if (angular.isFunction(url)) return url(u);   // <<<<< this line does the trick
        return url == u;
      };
    

    if (angular.isFunction(url)) return url(u); 行提供了直接传递函数的选项,并在版本 1.3.0-beta.3 中添加(如前所述)。 但是,如果您仍想将函数传递给以前的 AngularJS 版本,则可以通过为对象提供 test 方法来“欺骗” Angular 使其相信您传递了 RegExp。
    IE。替换:

    .whenGET(function (url) {...})
    

    与:

    .whenGET({test: function (url) {...}})
    

    另请参阅此short demo

    【讨论】:

    • 如果我删除“new”关键字,警报将不再执行,我得到“错误:意外请求:GET /users/1”
    • @Asterius:Aλ 虽然您已经设法解决了这个问题,但请查看我更新的答案,了解实际原因和可能的解决方案。
    • 好的,我现在理解错误了,我在阅读 1.3 文档时使用的是 1.2.24。感谢您的时间和演示!
    【解决方案2】:

    我通过在响应部分而不是 when 部分中使用函数找到了解决方案:

    $httpBackend.whenGET(new RegExp('\\/users\\/[0-9]+')).respond(
        function(method, url){
            var regexp = new RegExp('\\/users\\/([0-9]+)');
            var mockId = url.match(regexp)[1];
            return [200, users[mockId]];
        }
    });
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-10-19
      • 1970-01-01
      • 2018-03-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多