如何模拟get(id)请求

Ast*_*ius 4 angularjs angularjs-e2e

我正在构建一个应用程序原型并尝试模拟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]);
}
Run Code Online (Sandbox Code Playgroud)

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

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

我在角度文档中读到我应该能够用函数替换RegExp URI.我们的想法是从url中提取id以在response方法中使用它.然后我尝试了这个:

$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]);
Run Code Online (Sandbox Code Playgroud)

问题是url参数始终未定义.有什么想法实现我的目标?

gka*_*pak 6

通过使用new function(url)您的应用程序尝试从您的匿名函数实例化一个新对象,并将该新对象作为$httpBackend.whenGET()调用的第一个参数传递.
当然,在调用时whenGET()没有提供URL,因此它总是未定义的.

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

$httpBackend.whenGET(function (url) {
  ...
}).respond(users[id]);
Run Code Online (Sandbox Code Playgroud)

更新:
经过一些挖掘后发现,whenGET1.3.0-beta.3版本中添加了将函数作为第一个参数传递的选项.您正在阅读的文档可能是指最新的测试版,而您使用的是早期版本.
(请注意,即使版本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;
  };
Run Code Online (Sandbox Code Playgroud)

该行if (angular.isFunction(url)) return url(u);是提供直接传递函数的选项,并在版本1.3.0-beta.3中添加(如上所述).但是,如果你仍然希望将一个函数传递给之前的AngularJS版本,你可以通过提供一个带有test方法的对象来"欺骗"角度来相信你传递了一个RegExp .
即更换:

.whenGET(function (url) {...})
Run Code Online (Sandbox Code Playgroud)

有:

.whenGET({test: function (url) {...}})
Run Code Online (Sandbox Code Playgroud)

另见这个简短的演示.