【问题标题】:How to mock an AJAX request?如何模拟 AJAX 请求?
【发布时间】:2012-12-16 06:34:46
【问题描述】:

在端到端测试期间修改场景.js 以模拟 AJAX 请求的最简单方法是什么?

<!doctype html>
<html lang="en" ng-app="myApp">
<head>
  <meta charset="utf-8">
  <title>My Test AngularJS App</title>
  <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.0.2/angular.min.js"></script>
  <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.0.2/angular-resource.min.js"></script>

  <script language="javascript" type="text/javascript">
      angular.module('myApp', ['ngResource']);
      function PlayerController($scope,$resource){
        $scope.player = $resource('player.json').get();
      }
    </script>

</head>
  <body ng-controller="PlayerController">
    <p>Hello {{player.name}}</p>
  </body>
</html>

播放器从服务器上名为 player.json 的文件中正确获取,并且以下测试通过。如何将不同的 json 传递到此测试并防止获取回服务器?

/*
How do I pass in
player.json -> {"name":"Chris"}
*/
describe('my app', function() {

  beforeEach(function() {
    browser().navigateTo('../../app/index.html');
  });

  it('should load player from player.json', function() {
    expect(element('p:first').text()).
        toMatch("Hello Chris");
    pause();
  });

});

【问题讨论】:

    标签: testing angularjs jasmine end-to-end


    【解决方案1】:

    您应该使用$httpBackend from ngMockE2E module 模拟http 请求。查看文档。

    【讨论】:

    • 我的意思是我在文档中看不到 ngMockE2E 示例。我正在寻找将几行代码添加到scenes.js。
    • 如果我正确理解您的问题,您不需要修改scenario.js。 Caio 的回答是处理这种情况的标准方法
    • 好的。让我说清楚。我不明白如何按照 Caio 的建议去做。文档假设了一些魔法,例如“之后,使用这个新模块引导您的应用程序。”。如何做到这一点?
    • 明确地说,ngMockE2E 代码进入哪个文件?需要如何修改 runner.html 或场景.js 文件才能让魔法发生?
    • 文档说you have to create a module that depends on the ngMockE2E: angular.module('myApp', 'ngMockE2E']);。您需要包含 angular-mocks.js 才能正常工作。如果我没有错(我希望我是),似乎你不能在这个场景中嘲笑它。但是看到了一些关于它的争议herehere
    【解决方案2】:

    目前看来,您不能只修改场景.js 以包含 $httpBackend 模拟。您将不得不添加一些其他代码来支持它。

    对我来说最好的方法似乎是以下

    在包含“ngMockE2E”的测试文件夹中添加一个 myAppTest.js,这样您就不需要污染现有的 app.js

    'use strict';
    
    angular.module('myAppTest', ['myApp', 'ngMockE2E'])
    .run(function($httpBackend) {
        var user = {name: 'Sandra'};
        $httpBackend.whenGET('/api/user').respond(user); 
    });
    

    然后添加一个单独的 test-index.html,它使用新的 myAppTest.js。请注意,您需要包含 angular-mocks.js。 (这使您的生产 html 文件保持完整且没有模拟)

    <!doctype html>
    <html lang="en" ng-app="myAppTest">
    <head>
      <script src="lib/angular/angular.js"></script>
      <script src="lib/angular/angular-resource.js"></script>
      <script src="../test/lib/angular/angular-mocks.js"></script>
      <script src="js/app.js"></script>
      <script src="js/controllers.js"></script>
      <script src="../test/e2e/myAppTest.js"></script>
    </head>
    <body>
      <div ng-view></div>
    </body>
    </html>
    

    然后在您的场景中,只需在运行其他测试之前引用您的新 test-index.html。

    beforeEach(function() {
       browser().navigateTo('../../app/test-index.html#/');
    });
    

    我改编了这个例子:

    https://github.com/stephennancekivell/angular_e2e_http/tree/ngMockE2E

    【讨论】:

    • 您打算如何在原始应用中测试路线?路由配置了应用名称
    【解决方案3】:

    首先,将 angular-mocks.js 和您将在其中创建模块的文件(例如 app.js)添加到包含 ng-app 声明的 index.html 页面。

    <html lang="en" ng-app="myApp">
      <head>
        <script src="js/app.js"></script>
        <script src="../test/lib/angular/angular-mocks.js"></script>
        ...
    

    然后在 app.js 文件中定义模块并添加模拟响应。

    var myAppDev = angular.module('myApp', ['ngResource','ngMockE2E']);
    
    myAppDev.run(function($httpBackend) {
        var user = {name: 'Sandra'};
        $httpBackend.whenGET('/api/user').respond(user); 
    });
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-07-27
      • 1970-01-01
      • 1970-01-01
      • 2012-04-11
      • 1970-01-01
      • 2018-03-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多