Как проверить, заполняется ли область после трансляции и оценки процесса перенаправления URL?

Обновлено: в этом контроллере я пытаюсь протестировать процесс входа пользователя в систему, и он вызывает метод loginRequest в WebService для отправки учетных данных пользователя в виде сообщения для входа. Контроллер получает сообщение loginreply. Если процесс входа в систему прошел успешно, должно произойти перенаправление URL-адреса. Я использовал шпионские объекты Jasmine, чтобы издеваться над функциональностью WebService.

Было несколько подобных вопросов, и они помогли мне несколько сузить круг проблем. Но я все еще сталкиваюсь с некоторыми проблемами при правильной настройке этой функции модульного тестирования. Поэтому я решил опубликовать обновление на свой первоначальный вопрос.

Полезные вопросы о переполнении стека

Полезные внешние ресурсы

Но в настоящее время у меня возникла проблема с оценкой статуса полученного сообщения и оценкой процесса перенаправления URL. Как проверить, заполняется ли область после трансляции ($scope.msg)? Это прекрасно работает в самом приложении, просто не знаю, как это проверить.

У меня есть контроллер с прослушивателем событий в моем приложении Angular, определенный следующим образом.

Код AngularJS

Apps.controller('loginCtrl',['$scope','$location','WebService','$timeout','$log','$http',
    function($scope,$location,WebService,$timeout,$log,$http)
    {
        $scope.login = function()
        {
            var loginMsg = {};
            loginMsg.UserName = $scope.username;
            loginMsg.Password = $scope.password;
            WebService.loginRequest($location.host(),$location.port(),"Check","'?'",loginMsg);
        }

      //Error attempting to access msg in Unit test
        $scope.$on('LSuccess_msg',function(e,msg)
       {      
      //These variables can be accessed in the Unit test    
        $scope.myEventCalled = true;
        $scope.response = msg;    

        if(angular.equals(msg.Status,"LOGIN_SUCCESS"))
       {
         $timeout(function ()
        {
       //Need to test this
         window.location.href = "http://"+<--custom redirection URL is added here-->;}, 5);
            }
        });
    }]);

Модульный тест, используемый для проверки контроллера

    "use strict";

    describe("Controller : Login controller", function() {
    var $scope, ctrl, $location, $timeout, WebService, httpBackend, msgdata;

    beforeEach(module('Apps'));
    beforeEach(inject(function($rootScope, $controller, _$timeout_, _$location_, $httpBackend){
          $scope    =  $rootScope.$new();
          $timeout  = _$timeout_;
          $location = _$location_;
          httpBackend = $httpBackend;

          var loginMsg={};//populate message

              msgdata={EMail:"[email protected]",FullName:"Viranga Indira",SessionId:"1114335860", Status:"LOGIN_SUCCESS", 
          UserID:"c7232d47",_msgType:"com.ust.sharedmsgs.LoginReply_msg", 
                  };

          WebService = jasmine.createSpyObj(WebService, ["loginRequest"]);
                  WebService.loginRequest($location.host(),$location.port(),"Check","'?'",loginMsg);

          ctrl = $controller('loginCtrl',{
          $scope: $scope,
          $location: $location,
          WebService: WebService,
          $timeout: $timeout
          });
          $scope.$digest();
    }));

    describe("Controller : Login controller", function(){

        it("creates spies for the requested Service", function() {
            expect(WebService.loginRequest).toBeDefined();
        });

        it("tracks that the spies were called", function() {
            expect(WebService.loginRequest).toHaveBeenCalled();
        });

        it('should call loginRequest WebServiceMock', function ()
        {
        $scope.username = '[email protected]';
        $scope.password = 'viranga123';
        $scope.$digest();

        $scope.login();
        expect($scope.username).toEqual('[email protected]');
        expect($scope.password).toEqual('viranga123');
        expect(WebService.loginRequest).toHaveBeenCalled();
        });

      var $rootScope;
      beforeEach(inject(function($injector) {
      $rootScope = $injector.get('$rootScope');
      $rootScope.$broadcast('LSuccess_msg', msgdata);
      }));

      describe("Boradcast response", function() {
               it("should broadcast Response message", function() {
               expect($scope.myEventCalled).toBe(true);
               expect($scope.msg).not.toBe(null);

             //$scope.msg.Status check fails
             //expect($scope.msg.Status).toEqual('LOGIN_SUCCESS'); 

             //$scope.response related checks can be evaluated
               expect($scope.response).not.toBe(null);
               expect($scope.response.EMail).toEqual('[email protected]');
               expect($scope.response.Status).toEqual('LOGIN_SUCCESS');
               expect($scope.response.FullName).toEqual('Viranga Indira');
         });
       });
    });
 });

Сообщение об ошибке выдается, если ожидание раскомментировано

Chrome 36.0.1985 (Windows 7) Controller : Login controller Controller : Login controller 
Boradcast response should broadcast Response message FAILED
TypeError: Cannot read property 'Status' of undefined at null.<anonymous>

Любые указания о том, как я могу проверить статус полученного сообщения (например, $scope.msg.Status) и как протестировать процесс перенаправления URL-адресов, будут высоко оценены. Почему $scope.msg.Status недоступен в этом тесте?

Можно ли использовать шпионские объекты для улучшения этого теста, особенно для проверки $scope.$on в AngularJS?


person Gehan    schedule 15.08.2014    source источник
comment
@Ben Lesh - Любые сведения о том, как я могу проверить полученное сообщение в блоке $scope.$on (например, $scope.$on('LSuccess_msg',function(e,msg){...}). Как я могу обратиться к параметру msg в моем модульном тесте?   -  person Gehan    schedule 03.09.2014


Ответы (1)


Похоже, ваш вопрос:

Как проверить window.location?

Один ответ здесь — создать службу, которая упаковывает местоположение окна. Что-то очень простое, например:

app.factory('windowLocation', function($window) {
  return $window.location;
});

Затем туда, где вам это нужно, вы вводите его:

app.controller('MyCtrl', function($scope, windowLocation) {
  $scope.foo = function(url){
    windowLocation.href = url;
  });
});

Поэтому протестировать его так же просто, как имитировать его и предоставить его вашему контроллеру (или службе).

$controller('MyCtrl', {
  $scope: someScope,
  windowLocation: mockWindowLocation,
});

а затем подтвердите, что href был изменен на вашем макете:

describe('$scope.foo', function() {
  it('should update windowLocation.href', function(){
    $scope.foo('whatever');
    expect(mockWindowLocation.href).toBe('whatever');
  });
});

Помимо этого, единственное, что, как я вижу, потенциально усложняет ваш код, — это $timeout, которым вы обернули изменение местоположения. Если это не нужно, удалите его. Если это необходимо, вам просто нужно сделать асинхронный тест jasmine, который, я думаю, довольно хорошо задокументирован в Интернете.

Удачи, и я надеюсь, что этот ответ поможет вам.

person Ben Lesh    schedule 20.08.2014