在AngularJS应用程序中运行Karma单元测试时出现“意外请求”错误

时间:2014-12-25 20:01:17

标签: angularjs unit-testing angular-ui-router

我已经看到了一些有关这方面的问题,但所有问题都是针对每个案例的,我在这些帖子中找不到解决方案。

我有一个当前的控制器:

    function Login(authService, $scope) {

    var vm = this;

    vm.submit = submit;

    vm.form = {};

    function submit() {
      if ($scope.loginForm.$invalid) {
        vm.invalid = true;
        return;
      } else {
        var data = {
          usr: vm.form.email,
          pwd: vm.form.password,
          vendorId: 99
        };
        authService.login(data).then(success, error);
      }
    }

    function success(res) {
      if (res.data) {
        //Do stuff
      }
    }

    function error(error) {
      console.log("Error ", error);
    }

  }

以下单元测试:

describe('Login', function() {
    beforeEach(module('app'));

    var loginCtrl, scope, $httpBackend, authService;
    var loginResponse = [{
        "data": {
            "avatar": "avatar",
            "gender": "M",
            "hid": "hid,
            "id": "id",
            "role": "Adult",
            "token": "token"
        }
    }];
    var loginRequest = { "usr": "test@teste.com", "pwd": "123teste!", "vendorId": 99 };

    beforeEach(inject(function($rootScope, _$httpBackend_, $controller, _authService_) {
        $httpBackend = _$httpBackend_;
        scope = $rootScope.$new();
        loginCtrl = $controller('Login', {
            $scope: scope
        });
        authService = _authService_;

    }));

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

    describe("submit", function() {
        it("should send login data to the server", function() {
            // expect(loginCtrl.login).toBe(false);

            //Tells the $httpBackend service to expect a POST call to be made to a service and that it will return
            //loginResponse object that was defined before
            $httpBackend.expectPOST('api/current/api/login').respond(loginResponse);

            //Execution of the service
            var deferred = authService.login(loginRequest);
            var users;
            deferred.then(function(response){
                users = response.data;
            });
            // expect(loginCtrl.login).toBe(true);

            //Preserve the asynchronous nature of the call while at the same time be able to test the response of the call
            $httpBackend.flush();

            // dump(users);
            expect(users).toEqual(loginResponse);
            // expect(loginCtrl.login).toBe(true);
        });

    });



});

我收到错误:

Error: Unexpected request: GET signup/signup.html
No more request expected

我发现了为什么会出现这种错误(我认为)。我正在使用ui-router,似乎总是试图对路由器root做一个GET请求:

$urlRouterProvider.otherwise('/signup/');

$stateProvider
/* NOT AUTHENTICATED STATES */
  .state('signup', {
    url: '/signup/',
    templateUrl: 'signup/signup.html',
    controller: 'Signup as signupCtrl',
    data: {
      authorizedRoles: [AUTH_EVENTS.notAuthenticated]
    }
  })

现在我不知道为什么,或者如何解决它......有人能理解我做错了吗?

提前致谢!

编辑:authService

function authService($http, Session) {
    var service = {
      login             : login
    };
    return service;

    function login(credentials) {
      console.log('authservice:', credentials);
      return $http.post('api/current/api/login', credentials).then(function(res){
          if (res.data.data){
            var user = res.data.data;
              Session.create(user.id, user.hid, user.token, credentials.usr, user.role, user.gender);
          }
            return res.data;
      });
    }
    }

2 个答案:

答案 0 :(得分:0)

请求模板,但是您没有通知$ http模拟它 使用$ httpBackend

注册您的模板
$httpBackend.expect('GET', 'signup/signup.html');

https://docs.angularjs.org/api/ngMock/service/ $ httpBackend#期望

答案 1 :(得分:0)

更新了您的功能并尝试使用此代码。另一个选项是使用gulp在模板缓存中添加模板如果您使用gulp这个模板获取调用问题是非常具体的ui路由器和我已经看到在github上发布了针对它的bug。

$httpBackend.expectGET('signup/signup.html').respond(200);
$httpBackend.flush();
$httpBackend.expectPOST('api/current/api/login').respond(loginResponse);

            //Execution of the service
            var deferred = authService.login(loginRequest);
            var users;
            deferred.then(function(response){
                users = response.data;
            });
            // expect(loginCtrl.login).toBe(true);

            //Preserve the asynchronous nature of the call while at the same time be able to test the response of the call
            $httpBackend.flush();

            // dump(users);
            expect(users).toEqual(loginResponse);
            // expect(loginCtrl.login).toBe(true);