GVKun编程网logo

AngularJS + Jasmine:$ httpBackend不能按预期工作(angularjs stateprovider)

20

对于AngularJS+Jasmine:$httpBackend不能按预期工作感兴趣的读者,本文将会是一篇不错的选择,我们将详细介绍angularjsstateprovider,并为您提供关于$htt

对于AngularJS + Jasmine:$ httpBackend不能按预期工作感兴趣的读者,本文将会是一篇不错的选择,我们将详细介绍angularjs stateprovider,并为您提供关于$httpBackend(angularJS)中的URL参数、anglejs – Angular JS单元测试$httpBackend spec没有任何期望、Angular-mock之使用$httpBackend服务测试$http、AngularJS $ httpBackend-“预期没有更多请求”错误的有用信息。

本文目录一览:

AngularJS + Jasmine:$ httpBackend不能按预期工作(angularjs stateprovider)

AngularJS + Jasmine:$ httpBackend不能按预期工作(angularjs stateprovider)

我将 JasmineKarma 一起使用,以测试基于 Angular 构建的应用程序。

我必须测试加载用户数据的服务,并且使用 $ httpBackend 模拟响应。但是,当我运行测试时,出现两个错误:

  • 错误:没有等待刷新的请求!
  • 错误:请求不满意:GET https://api.github.com/users/wilk

模块:

''use strict'';app.service (''UserService'', [''$resource'', ''$q'', ''GITHUB_API_URL'', function ($resource, $q, GITHUB_API_URL) {  var userResource = $resource (GITHUB_API_URL + ''/users/:user'', {user: ''@user''}) ,      userModel = {};  return {    data: function () {        return userModel;    } ,    populate: function (user) {      var deferred = $q.defer () ,          userRequest = userResource.get ({user: user});      $q          .when (userRequest.$promise)          .then (function (data) {              userModel = data;              deferred.resolve (data);          });      return deferred.promise;    }  };}]);

测试:

''use strict'';describe (''Service: UserService'', function () {    beforeEach (module (''myApp''));    var $appInjector = angular.injector ([''myApp'']) ,        UserService = $appInjector.get (''UserService'') ,        GITHUB_API_URL = $appInjector.get (''GITHUB_API_URL'') ,        GITHUB_USER = $appInjector.get (''GITHUB_USER'') ,        $httpBackend;    beforeEach (inject (function ($injector) {        $httpBackend = $injector.get (''$httpBackend'');        $httpBackend            .when (''GET'', GITHUB_API_URL + ''/users/'' + GITHUB_USER)            .respond ({                login: GITHUB_USER ,                id: 618009            });    }));    afterEach (function () {        $httpBackend.verifyNoOutstandingExpectation ();        $httpBackend.verifyNoOutstandingRequest ();    });    describe (''when populate method is called'', function () {        it (''should returns user data'', function () {            $httpBackend.expectGET (GITHUB_API_URL + ''/users/'' + GITHUB_USER);            UserService.populate (GITHUB_USER);            $httpBackend.flush ();            expect(UserService.data ()).toEqual ({                login: GITHUB_USER ,                id: 618009            });        });    });});

假设GITHUB_API_URL等于 ‘ https://api.github.com/
‘,_而GITHUB_USER等于
‘wilk’_ 。

我正在使用 Karma-Jasmine 0.1.5AngularJS 1.2.6 (使用Angular
Mocks和方案1.2.6)运行此测试。

此代码有什么问题?

答案1

小编典典

让我们分别讨论每个错误:

错误:没有等待刷新的请求!

发生这种情况是因为没有通过请求$httpBackend,所以没有要刷新的东西。那是因为您在实例化UserService之前$httpBackend,所以Angular不知道它应该使用它而不是real
$http。如果您检出控制台,您会看到正在发送真实请求。

错误:请求不满意:GET
https://api.github.com/users/wilk

与上述相同的原因。由于$httpBackend服务未使用该服务,因此您创建的期望将永远无法实现。

考虑以上所有因素后,重构的规格如下:

describe (''Service: UserService'', function () {    var UserService,        GITHUB_API_URL,        GITHUB_USER,        $httpBackend;    beforeEach(function() {      module(''plunker'');      inject(function( _$httpBackend_, _UserService_, _GITHUB_API_URL_, _GITHUB_USER_) {        $httpBackend = _$httpBackend_;        UserService = _UserService_;        GITHUB_API_URL = _GITHUB_API_URL_;        GITHUB_USER = _GITHUB_USER_;      });    });    afterEach (function () {        $httpBackend.verifyNoOutstandingExpectation ();        $httpBackend.verifyNoOutstandingRequest ();    });    describe (''when populate method is called'', function () {        it (''should returns user data'', function () {            $httpBackend              .whenGET(GITHUB_API_URL + ''/users/'' + GITHUB_USER)              .respond ({                  login: GITHUB_USER,                  id: 618009              });            UserService.populate(GITHUB_USER);            $httpBackend.flush();            expect(UserService.data().login).toBe(GITHUB_USER);            expect(UserService.data().id).toBe(618009);        });    });});

柱塞

注意:我已经更改了一些注入方式,但是只要您先创建$httpBackend其他内容,您的操作就可以了。

$httpBackend(angularJS)中的URL参数

$httpBackend(angularJS)中的URL参数

是否可以在angularJS的$httpBackend中接收URL参数?我想做的事情如下:

$httpBackend.whenGET('/api/v1/users/{userId}').respond(function (method,url,data) {
    // somehow read {userId} and act differently depending on what the value is

    return [200];
});

拥有这个功能真的可以很容易地创建一个功能相当的模拟API(更容易开发前端应用程序而无需运行整个后端).

解决方法

您可以传递正则表达式而不是字符串作为URL.在回调函数中,从URL中提取userId,并回答您想要的内容.

anglejs – Angular JS单元测试$httpBackend spec没有任何期望

anglejs – Angular JS单元测试$httpBackend spec没有任何期望

我有一个单元测试,其中唯一的期望是发出http呼叫.我为此使用$httpBackend.expect().这样工作正常,单元测试失败,如果这个http请求没有(这是好的),并通过,如果http请求.

问题在于,即使想到这一点,茉莉花规范竞赛者对这个单元测试显示“SPEC HAS NO EXPECTATIONS”,这使我觉得我没有使用推荐的方式来测试一个http的呼叫.如何避免看到此讯息?

示例测试:

it('should call sessioncheck api',function () {
    inject(function ($injector,SessionTrackerService) {
        $httpBackend = $injector.get('$httpBackend');

        var mockResponse = { IsAuthenticated: true,secondsRemaining: 100 };
        $httpBackend.expect('GET','API/authentication/sessioncheck')
            .respond(200,mockResponse);

        SessionTrackerService.Start();

        jasmine.clock().tick(30001);
        $httpBackend.flush();
    });
});
我打电话来刷新如下:
expect($httpBackend.flush).not.toThrow();

我喜欢这种方法,因为测试代码清楚地说明了调用flush时应该怎么办.例如:

it('should call expected url',inject(function($http) {
    // arrange
    $httpBackend.expectGET('http://localhost/1').respond(200);

    // act
    $http.get('http://localhost/1');

    // assert
    expect($httpBackend.flush).not.toThrow();

}));

Angular-mock之使用$httpBackend服务测试$http

Angular-mock之使用$httpBackend服务测试$http

Angular-mock简介

Angular-mock模块为angular单元测试提供模块定义、加载、注入等支持。辅助Karma、Jasmine等JS测试工具来模拟angular方法,测试angular应用。除此之外,Angular-mock还扩展了ng的多个核心服务,使之可以被测试代码以同步的方式进行审查和控制。

安装

在HTML中引用:

<script src="angular.js">
<script src="angular-mocks.js">

还可以用以下方式下载或引用:

  • Bower

    
        bower install angular-mocks@X.Y.Z
  • code.angularjs.org

        "//code.angularjs.org/X.Y.Z/angular-mocks.js"

    X、Y、Z为你需要的AngularJS版本号。

然后在你的angular应用中启用ngMock模块:

angular.module(''app'', [''ngMock'']);

模块组件

对象

名称 描述
angular.mock ''angular-mocks.js''的命名空间,其中包含测试代码。

服务

名称 描述
$exceptionHandler 通过$exceptionHandler模拟实现重抛或记录错误信息。查看$exceptionHandlerProvider获取配置信息。
$log 模拟实现 $log 收集所有数组中已记录的日志信息(每一个记录等级一个数组)。这些数组被作为logs属性可每个具体等级的log方法获取。 例:对于等级error数组可被 $log.error.logs获取。
$interval 模拟实现$interval服务。
$httpBackend 为使用了$http service的应用提供单元测试的伪HTTP后台。
$timeout 该服务仅是一个简单的装饰器,为$timeout 服务添加了"flush"和"verifyNoPendingTasks" 方法。
$controller 为$controller提供了额外的bindings参数,这在测试使用了 bindToController 指令的控制器时很有用处。

以上介绍信息来自官方api,中文表述不清之处请点击链接查看英文描述。

测试框架

Karma

安装

npm install -g karma

配置

在你想要测试的项目目录下创建config


karma init karma.config.js

使用该命令将出现问答式设置,包括使用框架选择、包含文件/文件夹、测试监听端口、测试用浏览器、是否使用Require.js等。根据提示进行设置即可。

$http测试示例

$http service示例

该示例提供了两个测试,一个简单的$http服务及一个简单的字符串匹配测试。


var app = angular.module(''Application'', []);

app.controller(''MainCtrl'', function($scope, $http) {
    $http.get(''Users/users.json'').success(function(data){
        $scope.users = data;
    });
    $scope.text = ''Hello World!'';
});

将该文件保存为js/demo.js,测试时需按顺序将测试项目文件及依赖文件引入config.js。

使用$httpBackend设置伪后台

针对上面这个示例,测试的时候,我们不需要真实的发送HTTP请求来获取数据。如果可以只测试Service的逻辑,当发送请求时,我们将这个请求拦截下来,然后返回一个预定义好的数据即可:

describe(''MainCtrl'', function() {
    //我们会在测试中使用这个scope
    var scope, $httpBackend;

    //模拟我们的Application模块并注入我们自己的依赖
    beforeEach(angular.mock.module(''Application''));

    //模拟Controller,并且包含 $rootScope 和 $controller
    beforeEach(angular.mock.inject(function($rootScope, $controller, _$httpBackend_) {
        //设置$httpBackend冲刷$http请求
        $httpBackend = _$httpBackend_;
        $httpBackend.when(''GET'', ''Users/users.json'').respond([{
            id: 1,
            name: ''Bob''
        }, {
            id: 2,
            name: ''Jane''
        }]);
        //创建一个空的 scope
        scope = $rootScope.$new();

        //声明 Controller并且注入已创建的空的 scope
        $controller(''MainCtrl'', {
            $scope: scope
        });
    }));

    // 测试从这里开始
    it(''should have variable text = "Hello World!"'', function() {
        expect(scope.text).toBe(''Hello World!'');
    });
    it(''should fetch list of users'', function() {
        $httpBackend.flush();
        expect(scope.users.length).toBe(2);
        expect(scope.users[0].name).toBe(''Bob'');
        //输出结果以方便查看
        for(var i=0;i<scope.users.length;i++){
            console.log(scope.users[i].name);
        }
    });
});

以上示例中,可以使用$httpBackend.when和$httpBackend.expect提前设置请求的伪数据。最后在请求后执行$httpBackend.flush就会立即执行完成http请求。

将测试文件保存在test/demo-test.js中。

接下来在项目目录中找到设置好的config.js文件,在files数组中添加以下引用:


files: [
  ''ng/angular.js'',
  ''ng/angular-mocks.js'',
  ''js/demo.js'',
  ''test/demo-test.js''
],

为保证测试与项目代码分离,我建议将配置文件及测试代码单独存放在test目录,项目打包时可直接删除。

测试跑起来

写好测试后,使用


karma start config.js

让测试跑起来。karma默认端口9876,可以在config.js中设置。运行命令后,设置过的浏览器会自动运行,点击DEBUG按钮即可运行测试代码。

打开console,可以看到测试已经成功输出了。

$httpBackend常用方法

when

新建一个后端定义(backend definition)。

when(method, url, [data], [headers]);

expect

新建一个请求期望(request expectation)。

expect(method, url, [data], [headers]);

when和expect都需要4个参数method, url, data, headers, 其中后2个参数可选。

  • method表示http方法注意都需要是大写(GET, PUT…);<br/>

  • url请求的url可以为正则或者字符串;

  • data请求时带的参数,

  • headers请求时设置的header。

如果这些参数都提供了,那只有当这些参数都匹配的时候才会正确的匹配请求。when和expect都会返回一个带respond方法的对象。respond方法有3个参数status,data,headers通过设置这3个参数就可以伪造返回的响应数据了。

区别

$httpBackend.when$httpBackend.expect的区别在于:$httpBackend.expect的伪后台只能被调用一次(调用一次后会被清除),第二次调用就会报错,而且$httpBackend.resetExpectations可以移除所有的expect而对when没有影响。

快捷方法

when和expect都有对应的快捷方法whenGET, whenPOST,whenHEAD, whenJSONP, whenDELETE, whenPUT; expect也一样。

//when
whenGET(url, [headers]);
whenHEAD(url, [headers]);
whenDELETE(url, [headers]);
whenPOST(url, [data], [headers]);
whenPUT(url, [data], [headers]);
whenJSONP(url);
//expect
expectGET(url, [headers]);
expectHEAD(url, [headers]);
expectDELETE(url, [headers]);
expectPOST(url, [data], [headers]);
expectPUT(url, [data], [headers]);
expectPATCH(url, [data], [headers]);
expectJSONP(url);

参考

  • 官方API:ngMock

  • ngMock:$httpBackend

  • AngularJS tests with an http mock

  • 单元测试—AngularJS学习笔记

AngularJS $ httpBackend-“预期没有更多请求”错误

AngularJS $ httpBackend-“预期没有更多请求”错误

看来这是有效的解决方案,显示了如何使用$httpBacked
http://jsfiddle.net/EgMpe/8/

但就我而言:

路线

app.config([''$routeProvider'', function($routeProvider) { $routeProvider.    when(''/'',  {templateUrl: ''partials/user-list.html''}).

伪造的服务:

app.run(function($httpBackend) {        var users = [{"id":1,"name":"bob","email":"bob@bobs.com"}, {"id":2,"name":"bob2","email":"bob2@bobs.com"}]        $httpBackend.whenGET(''/rest/users'').respond(function(method,url,data) {            console.log("Getting users");            return [200, users, {}];        });    });

..

真实服务:

services.factory(''Users'', function($resource){    return $resource(''/rest/users'', {}, {        get:        {method: ''GET'', isArray:true}    });});

转到将我重定向到页面的“ /”路由时出现 错误user-list.html

错误:意外请求:GETpartials / user-list.html在$ httpBackend … / mysite / public /
angular / libs / angular-1.2.0 / angular-mocks.js:1060:9上没有更多请求了

问题1: 是否httpBackend阻止其他http要求?

我试图使用 passThrough 方法让http到达真实服务器端:

$httpBackend.whenGET(/^\/mysite\//).passThrough();

但这无济于事。

答案1

小编典典

啊..抱歉,我的RegEx错了:

如果输入 $httpBackend.whenGET(/partials/).passThrough();

然后所有人开始工作。

因此,我得到了教训:不要忘了说: passThrough(); 与正确的 RegEx

今天关于AngularJS + Jasmine:$ httpBackend不能按预期工作angularjs stateprovider的分享就到这里,希望大家有所收获,若想了解更多关于$httpBackend(angularJS)中的URL参数、anglejs – Angular JS单元测试$httpBackend spec没有任何期望、Angular-mock之使用$httpBackend服务测试$http、AngularJS $ httpBackend-“预期没有更多请求”错误等相关知识,可以在本站进行查询。

本文标签: