首页 文章

Angular / Karma - 预期和观察到的请求相同时出现“意外请求”错误

提问于
浏览
0

我是单元测试控制器的方法 . 我的应用程序在应用程序启动时触发了一些GET请求,当我运行测试时,我收到了意外的请求错误 .

这是我的控制器的登录方法 . 注意:我正在使用angular classy(因此使用非标准语法):

login: function() {
    var self = this,
        params,
        loginSuccess,
        user;

    if (self.$.user.email === '' || self.$.user.password === '') {

      self.$notification.alert({
        title: "Error",
        message: "Email and password can't be blank!"
      });

    } else {

      params = {
         user: self.$.user,
         position: self.Geolocation.currentPosition
      };

      self.$session.login(params).then(loginSuccess);

    }
};

这是测试:

describe("LoginController", function() {
  var scope, $rootScope, createController, $controller,
      $httpBackend, $session, session, $notification;

  var emptyCredentials = {
    email: "bleh",
    password: ""
  };

  beforeEach(angular.mock.module('myapp'));

  beforeEach(inject(function($injector){

    jasmine.getJSONFixtures().fixturesPath='base/unit/fixtures';

    $httpBackend = $injector.get("$httpBackend");

    $httpBackend
      .when('GET', 'http://myapp.com:3000/api/v2/apps/3?app_id=3')
      .respond(200, getJSONFixture('apps.json'));
    $httpBackend
      .when('GET', 'http://myapp.com:3000/api/v2.2/locations?app_id=3')
      .respond(200, getJSONFixture('locations.json'));
    $httpBackend
      .when('GET', 'http://myapp.com:3000/api/v2/users/me?app_id=3')
      .respond(200, getJSONFixture('me.json'));

    $session = $injector.get("$session");

    // mock session so that session.loggedIn doesn't return true
    // on subsequent tests
    session = {
      setUser: function() {
      },
      loggedIn: function() {
        return false;
      },
      authPath: function() {
        return false;
      },
      login: $session.login
    };

    $rootScope = $injector.get("$rootScope");
    $controller = $injector.get("$controller");
    $notification = $injector.get("$notification");
    scope = $rootScope.$new();

    createController = function () {
      return $controller('LoginController', {
        $scope: scope,
        $session: session,
        $notification: $notification
      });
    };

    // spies on $notification.alerts
    spyOn($notification, 'alert');

  }));

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

    $httpBackend.resetExpectations();

  });

  it('should show alert on empty login credentials', function() {

    $httpBackend.expectGET('http://myapp.com:3000/api/v2/apps/3?app_id=3');
    $httpBackend.expectGET('http://myapp.com:3000/api/v2.2/locations?app_id=3');
    $httpBackend.expectGET('http://myapp.com:3000/api/v2/users/me?app_id=3');

    var controller = createController();
    scope.user = emptyCredentials;
    scope.login();

    $httpBackend.flush();

    expect($notification.alert).toHaveBeenCalledWith({
      title: "Error",
      message: "Email and password can't be blank!"
    });

  });

当我运行业力时,我得到这些错误:

Error: Unexpected request: GET http://myapp.com:3000/api/v2/apps/3?app_id=3
Expected GET http://myapp.com:3000/api/v2/apps/3?app_id=3
    at $httpBackend (/Users/myapp/vendor/angular-mocks/angular-mocks.js:1178:9)
    at sendReq (/Users/myapp/vendor/angular/angular.js:8315:9)
    at serverRequest (/Users/myapp/vendor/angular/angular.js:8049:16)
    at wrappedCallback (/Users/myapp/vendor/angular/angular.js:11520:81)
    at wrappedCallback (/Users/myapp/vendor/angular/angular.js:11520:81)
    at /Users/myapp/vendor/angular/angular.js:11606:26
    at Scope.$eval (/Users/myapp/vendor/angular/angular.js:12632:28)
    at Scope.$digest (/Users/myapp/vendor/angular/angular.js:12444:31)
    at Function.$httpBackend.flush (/Users/myapp/vendor/angular-mocks/angular-mocks.js:1438:16)
    at null.<anonymous> (/Users/myapp/test/unit/controllers/login_controller.test.js:104:18)
Error: Unexpected request: GET http://myapp.com:3000/api/v2.2/locations?app_id=3
Expected GET http://myapp.com:3000/api/v2/apps/3?app_id=3
    at $httpBackend (/Users/myapp/vendor/angular-mocks/angular-mocks.js:1178:9)
    at sendReq (/Users/myapp/vendor/angular/angular.js:8315:9)
    at serverRequest (/Users/myapp/vendor/angular/angular.js:8049:16)
    at wrappedCallback (/Users/myapp/vendor/angular/angular.js:11520:81)
    at wrappedCallback (/Users/myapp/vendor/angular/angular.js:11520:81)
    at /Users/myapp/vendor/angular/angular.js:11606:26
    at Scope.$eval (/Users/myapp/vendor/angular/angular.js:12632:28)
    at Scope.$digest (/Users/myapp/vendor/angular/angular.js:12444:31)
    at Function.$httpBackend.verifyNoOutstandingExpectation (/Users/myapp/vendor/angular-mocks/angular-mocks.js:1470:16)
    at null.<anonymous> (/Users/myapp/test/unit/controllers/login_controller.test.js:75:18)

仅供参考login_controller.test.js的第104行是 $httpBackend.flush() . login_controller.test.js的第75行是 $httpBackend.verifyNoOutstandingExpectation() .

我相信$ httpBackend.when()在应用程序启动之前被调用(因此在应用程序启动的请求被触发之前),但也许这不是真的 . 奇怪的是,错误报告它发现XXX的意外请求,并且下一行表示它期望同一路径的请求!所以不确定为什么会这样 .

运行Angular 1.2.21,Angular Mocks 1.2.21

任何人都可以向我解释为什么我看到这个错误,我能做些什么来正确刷新和处理这些请求?

谢谢 .

2 回答

  • 0

    问题是现在$ http甚至对请求拦截器使用promises,因此验证在$ httpBackend获取请求之前发生 . 尝试添加$ rootScope . $ digest();你会得到“没有更多的要求” .

    参考:https://github.com/angular/angular.js/issues/5453

  • 1

    我弄清楚发生了什么:

    事实证明,供应商插件正在扩展本机String对象,重新定义了match()方法 . 这与角度模拟如何将期望与请求进行比较相矛盾,因此错误地抛出了错误 .

    如果您碰巧遇到此问题(预期请求和观察到的请求相同),请查找扩展本机String对象的插件或库 .

    例如,Mootools这样做会导致这个问题 .

相关问题