Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/security/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Angularjs 角度e2e测试中的模拟$httpBackend_Angularjs_Mocking_Acceptance Testing_Karma Runner_End To End - Fatal编程技术网

Angularjs 角度e2e测试中的模拟$httpBackend

Angularjs 角度e2e测试中的模拟$httpBackend,angularjs,mocking,acceptance-testing,karma-runner,end-to-end,Angularjs,Mocking,Acceptance Testing,Karma Runner,End To End,有人知道如何在e2e测试中模拟$httpBackend吗? 其思想是在travis ci上运行测试时截取XHR请求。 我正在使用karma代理运行在travis上的rails应用程序中的资产和部分。 我想在没有实际数据库查询的情况下进行验收测试 这是我的karma配置文件的一部分: ... files = [ MOCHA, MOCHA_ADAPTER, 'spec/javascripts/support/angular-scenario.js', ANGULAR_SCENARI

有人知道如何在e2e测试中模拟$httpBackend吗? 其思想是在travis ci上运行测试时截取XHR请求。 我正在使用karma代理运行在travis上的rails应用程序中的资产和部分。 我想在没有实际数据库查询的情况下进行验收测试

这是我的karma配置文件的一部分:

...
files = [
  MOCHA,
  MOCHA_ADAPTER,

  'spec/javascripts/support/angular-scenario.js',
  ANGULAR_SCENARIO_ADAPTER,

  'spec/javascripts/support/angular-mocks.js',
  'spec/javascripts/e2e/**/*_spec.*'
];
...

proxies = {
  '/app': 'http://localhost:3000/',
  '/assets': 'http://localhost:3000/assets/'
};
...
以下是我的等级库文件的一部分:

beforeEach(inject(function($injector){
  browser().navigateTo('/app');
}));

it('should do smth', inject(function($rootScope, $injector){
  input('<model name>').enter('smth');
  //this is the point where I want to stub real http query
  pause();
}));
但这不是在我的测试运行的iframe中使用的

我的下一次尝试是使用angular.scenario.dsl,下面是代码示例:

angular.scenario.dsl('mockHttpGet', function(){
  return function(path, fakeResponse){
    return this.addFutureAction("Mocking response", function($window, $document, done) {
      // I have access to window and document instances 
      // from iframe where my tests run here
      var $httpBackend =  $document.injector().get(['$httpBackend']);
      $httpBackend.expectGET(path).respond(fakeResponse)
      done(null);
    });
  };
});
用法示例:

it('should do smth', inject(function($rootScope, $injector){
  mockHttpGet('<path>', { /* fake data */ });
  input('search.name').enter('mow');
  pause();
}));
it('should do smth',inject(函数($rootScope,$injector){
mockHttpGet(“”,{/*假数据*/});
输入('search.name')。输入('mow');
暂停();
}));
这会导致以下错误:

<$httpBackend listing>  has no method 'expectGET'
没有“expectGET”方法

所以,在这一点上,我不知道下一步。有没有人尝试过这样做,这种类型的存根真的可能吗?

这感觉更像是单元/规范测试。一般来说,您应该在单元/规范测试中使用模拟,而不是e2e/集成测试。基本上,可以将e2e测试看作是在一个主要集成的应用程序上断言期望值……模仿东西有点违背e2e测试的目的。事实上,我不确定karam会如何将angular-mocks.js插入到正在运行的应用程序中

规格测试可能看起来像

describe('Controller: MainCtrl', function () {
    'use strict';

    beforeEach(module('App.main-ctrl'));

    var MainCtrl,
        scope,
        $httpBackend;

    beforeEach(inject(function ($controller, $rootScope, $injector) {
        $httpBackend = $injector.get('$httpBackend');
        $httpBackend.when('GET', '/search/mow').respond([
            {}
        ]);
        scope = $rootScope.$new();
        MainCtrl = $controller('MainCtrl', {
            $scope: scope
        });
    }));

    afterEach(function () {
        $httpBackend.verifyNoOutstandingExpectation();
        $httpBackend.verifyNoOutstandingRequest();
    });

    it('should search for mow', function () {
        scope.search = 'mow';
        $httpBackend.flush();
        expect(scope.accounts.length).toBe(1);
    });
});

如果您真的试图在E2E测试中模拟后端(这些测试称为场景,而规范用于单元测试),那么这就是我在之前工作的项目中所做的

我正在测试的应用程序名为
studentsApp
。这是一个通过查询RESTAPI来搜索学生的应用程序。我想在不实际查询api的情况下测试应用程序

我创建了一个名为
studentsapdev
的E2E应用程序,我将
studentsApp
ngMockE2E
注入其中。在这里,我定义了mockBackend应该期望的调用和返回的数据。以下是我的
studentsapdev
文件的示例:

"use strict";

// This application is to mock out the backend. 
var studentsAppDev = angular.module('studentsAppDev', ['studentsApp', 'ngMockE2E']);
studentsAppDev.run(function ($httpBackend) {

    // Allow all calls not to the API to pass through normally
    $httpBackend.whenGET('students/index.html').passThrough();

    var baseApiUrl = 'http://localhost:19357/api/v1/';
    var axelStudent = {
        Education: [{...}],
        Person: {...}
    };
    var femaleStudent = {
        Education: [{...}],
        Person: {...}
    };
    $httpBackend.whenGET(baseApiUrl + 'students/?searchString=axe&')
        .respond([axelStudent, femaleStudent]);
    $httpBackend.whenGET(baseApiUrl + 'students/?searchString=axel&')    
        .respond([axelStudent, femaleStudent]);
    $httpBackend.whenGET(baseApiUrl + 'students/?searchString=axe&department=1&')
        .respond([axelStudent]);
    $httpBackend.whenGET(baseApiUrl + 'students/?searchString=axe&department=2&')
        .respond([femaleStudent]);
    $httpBackend.whenGET(baseApiUrl + 'students/?searchString=axe&department=3&')    
        .respond([]);

    ...

    $httpBackend.whenGET(baseApiUrl + 'departments/?teachingOnly=true')
        .respond([...]);
    $httpBackend.whenGET(baseApiUrl + 'majors?organization=RU').respond([...]);
});

然后,我在Jenkins CI服务器中迈出了第一步,将
studentsApp
替换为
studentsapdev
,并在主index.html文件中添加对
angular mocks.js
的引用。

模拟后端是构建复杂的angular应用程序的重要一步。它允许在不访问后端的情况下进行测试,您不需要测试两次,并且不需要担心依赖性

是一种简单的方法,可以通过API的不同响应来测试应用程序的行为

它允许您将不同场景的模拟API响应集定义为JSON文件

它还允许您轻松地更改场景。它通过允许 你需要用不同的模拟文件组成“场景”

如何将其添加到应用程序中 将所需文件添加到页面中后,只需将
方案
作为依赖项添加到应用程序中:

angular
  .module('yourAppNameHere', ['scenario'])
  // Your existing code here...
一旦您将其添加到应用程序中,就可以开始为API调用创建模拟

假设您的应用程序进行以下API调用:

$http.get('/games').then(function (response) {
  $scope.games = response.data.games;
});
您可以创建一个
默认
模拟文件:

someGames.json的示例

{
  "httpMethod": "GET",
  "statusCode": 200,
  "uri": "/games",
  "response": {
    "games": [{"name": "Legend of Zelda"}]
  }
}
{
  "httpMethod": "GET",
  "statusCode": 200,
  "uri": "/games",
  "response": {
    "games": []
  }
}
加载应用程序时,对
/games
的调用将返回
200
{“games”:[{“name”:“塞尔达传奇”}]}

现在让我们假设您希望为同一API调用返回不同的响应,您可以通过更改URL将应用程序置于不同的场景中,例如
?场景=无游戏

no games
场景可以使用不同的模拟文件,例如:

{
  "_default": [
    "games/someGames.json"
  ],
  "no-games": [
    "games/noGames.json"
  ]
}
noGames.json的示例

{
  "httpMethod": "GET",
  "statusCode": 200,
  "uri": "/games",
  "response": {
    "games": [{"name": "Legend of Zelda"}]
  }
}
{
  "httpMethod": "GET",
  "statusCode": 200,
  "uri": "/games",
  "response": {
    "games": []
  }
}
现在,当您加载应用程序时,对
/games
的调用将返回
200
{“games”:[]}

场景由清单中的各种JSON模拟组成,如下所示:

{
  "_default": [
    "games/someGames.json"
  ],
  "no-games": [
    "games/noGames.json"
  ]
}

然后,您可以排除模拟文件并去除生产应用程序中的
场景
依赖项。

您如何配置karma,使其在规范中具有“注入”功能?我的测试不断收到ReferenceError,不需要设置和创建一个单独的应用程序来模拟$httpBackend。我在这里描述了如何设置它,以便它可以同时用于单元测试和E2E测试:。噢,这是一个很好的解决方案,迪达,谢谢你的评论。这肯定是我下一次必须模拟后端的时候要研究的东西。@Dida上面的链接现在不起作用了。你能对你所做的做一个简短的解释吗?也许是一个新的答案。谢谢。同时,您可以使用archive.org上的存档版本:代码与问题无关-问题与单元测试无关,代码用于Jasmine单元测试注入