0

Angular WebApp を開発していますが、BackEnd がまだ準備できていないため、偽のバックエンド ( $httpBackend) を使用して REST 要求をテストしています。

これは app.js で次のように定義されています。

// we want to use $httpBackend mock
app.config(function($provide) {
  $provide.decorator('$httpBackend', angular.mock.e2e.$httpBackendDecorator);
});
// define our fake backend
app.run(function($http, $httpBackend, url) {
  //Escape string to be able to use it in a regular expression
    function regEsc(str) {
        return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
    }

  // Mocking the login request
  //define the success var
  var user = {username: "me@stuff.it", password: "pass"};
  var userResponse = {
       "succes": "true",
       "user":{
       "id":"8490394",
       "username": "me",
       "token": "asd8u09u900asduijjaijjHJ"
      }
  };
  //success case
  $httpBackend.whenPOST(url.login, user).respond(200,userResponse);

  //other cases
  $httpBackend.whenPOST(url.login).respond(403,{success: false, message: 'Wrong username or password'});

  //let pass all views request
  $httpBackend.whenGET(function(string){
    console.log(string);
    return true;
  }).passThrough();

  $httpBackend.whenGET( RegExp( regEsc( "views/" ) ) ).passThrough();
});

そして、アプリケーションを実行すると正しく動作しますgrunt serve

問題は、私が作成したテストを実行しようとしたときに始まります (Jasmine で、Karma を介して実行されます)。ここでは、サンプル テストを示します。

'use strict';

describe('Service: Loginservice', function () {

  // load the service's module
  beforeEach(module('cmmApp'));

  // instantiate service
  var Loginservice, $rootScope, $httpBackend, url;
  beforeEach(inject(function (_Loginservice_, _$rootScope_ , $injector, _url_) {
    Loginservice = _Loginservice_;
    $rootScope = _$rootScope_;
    url = _url_;

    //questo serve per iniettare httpBackend
    $httpBackend = $injector.get('$httpBackend');

    $httpBackend.when('POST', url.login, {username:     "me@stuff.it",password:"pass"}).respond({success: true, user:{"id":"8490394","username": "me","token": "asd8u09u900asduijjaijjHJ"}});

    $httpBackend.whenPOST(url.login).respond(403, {success: false, message: 'Wrong username or password'});
  }));

it('should return user object', function () {

    var f;

    //se i valori sono corretti ritona un oggetto che contiene l'utente
    inject(function(Loginservice, $rootScope){
      Loginservice.login({username:"me@stuff.it",password:"pass"}).then(function(res){
        f = res;
      }); //end login

      //this trigger the promise
      $rootScope.$digest();

      //this trigger the http request
      $httpBackend.flush();

      expect(f).toEqual({success: true, user:{"id":"8490394","username": "me","token": "asd8u09u900asduijjaijjHJ"}});
    }); //end inject
  });

app.js から偽のバックエンド構成を削除すると、完全に機能しますが、そのままにしておくと、カルマ レポートが表示されます。Error: No pending request to flush !

これは、app.js で宣言されたインターセプターがトリガーされ、テストで定義された $httpBackend がリクエストでトリガーされないようにするためだと思います。

この問題を解決する方法について何か考えはありますか?

前もって感謝します

4

2 に答える 2

0

ngMockE2E は、単体テストで httpBackend を役に立たなくします。私は同じことで苦労しました。私は今、すべてのモック オブジェクトをモジュールなどに入れ、my.mocksそれを e2e テストと単体テストで使用しています。

e2e テストとバックエンドレス開発のために、ブートストラップされ、モジュール、モジュール、およびモジュールappDevを必要とするモジュールがあります。appmy.mocksngMockE2E

単体テストでは、ロードappするとモックが appDev コードと基本的に同じ when() を実行します。複製するのは本当にばかげているように思えますが、同時に、エラーをスローするデータを使用してテストしたいことがよくあります。そして、e2e 応答とは別に、いくつかのカスタム ユニット テスト応答を見つけました。

于 2015-02-16T20:54:52.373 に答える
0

$httpBackendつまり、Angular を介して実行されていないアプリ内の XHR は、定義した偽のデータを返しません。

もう 1 つの方法は、XMLHttpRequestシミュレートするサービスへの呼び出しをインターセプトするためにモンキー パッチを適用し、それらをクライアント側で実行されている疑似 RESTful サービスに渡すことです。それはまさにFakeRestが行うことなので、見てみたいと思うかもしれません。

于 2015-10-14T07:01:53.337 に答える