2015-01-22 1 views
3

У меня здесь серьезная проблема. Мое приложение опирается на функциональность SignalR, но из-за этого я не могу написать модульные тесты. Я новичок в тестировании фреймворков и использовал Jasmine только в простых случаях. SignalR оказалась для меня слишком сложной задачей, но мне нужно понять, как я могу ее успешно протестировать. Это мой CommsApp.ts файл [машинопись]:Проблемы с тестированием SignalR с жасмином в угловом приложении

/// <reference path="References.ts" /> 
var commsAnimationsModule = angular.module('forge.communications.animations', ['ngAnimate']); 
var commsDirectivesModule = angular.module('forge.communications.directives', []); 
var commsServicesModule = angular.module('forge.communications.services', []); 
var commsFiltersModule = angular.module('forge.communications.filters', []); 

var commsApp = angular.module('forge.communications.CommsApp', 
    [ 
     'ngRoute', 
     'ngAnimate', 
     'cfValidation', 
     'ui.bootstrap', 
     'forge.communications.animations', 
     'forge.communications.directives', 
     'forge.communications.services', 
     'forge.communications.filters', 
     'angularFileUpload', 
     'timeRelative' 
    ]); 

commsApp.config(function ($routeProvider: ng.route.IRouteProvider, $locationProvider: any) { 

     $locationProvider.html5Mode(true); 
     $routeProvider. 
      when('/scheduled-messages', { 
       templateUrl: '/forge/CommsApp/js/Controllers/ScheduledMessageList/ScheduledMessageList.html', 
       controller: 'ScheduledMessageListController' 
      }). 
      when('/geotriggered-messages', { 
       templateUrl: '/forge/CommsApp/js/Controllers/GeoMessageList/GeoMessageList.html', 
       controller: 'GeoMessageListController' 
      }). 
      when('/scheduled-message/create', { 
       templateUrl: '/forge/CommsApp/js/Controllers/CreateScheduledMessage/CreateScheduledMessage.html', 
       controller: 'CreateScheduledMessageController' 
      }). 
      when('/scheduled-message/edit/:id', { 
       templateUrl: '/forge/CommsApp/js/Controllers/EditScheduledMessage/EditScheduledMessage.html', 
       controller: 'EditScheduledMessageController' 
      }). 
      when('/geotriggered-message/create', { 
       templateUrl: '/forge/CommsApp/js/Controllers/CreateGeotriggeredMessage/CreateGeotriggeredMessage.html', 
       controller: 'CreateGeotriggeredMessageController' 
      }). 
      when('/geotriggered-message/edit/:id', { 
       templateUrl: '/forge/CommsApp/js/Controllers/EditGeotriggeredMessage/EditGeotriggeredMessage.html', 
       controller: 'EditGeotriggeredMessageController' 
      }). 
      otherwise({ 
       redirectTo: '/scheduled-messages' 
      }); 
    }); 

commsApp.run(function ($rootScope: ICommsRootScope, commsSignalrEventService: CommsSignalrEventService, commsMgmtHttpService: CommsMgmtHttpServiceClient) { 

    // set up the items on the root scope 
    $rootScope.SelectedLocale = 'en-ie'; 
    $rootScope.ForgeApplicationKey = "9496B737-7AE2-4FBD-B271-A64160759177"; 
    $rootScope.AppVersionString = "1.0.0"; 
    $rootScope.SessionToken = getCookie("ForgeSessionToken"); 

    commsSignalrEventService.initialize().done(() => { 
     // send any messages about a new user logging in to the application here. 
    }); 

    // call this at app startup to pre-cache this data for the create and edit pages 
    commsMgmtHttpService.GetUpdateMessageEditorOptions(); 
}); 

function getCookie(name:string) { 
    var value = "; " + document.cookie; 
    var parts = value.split("; " + name + "="); 
    if (parts.length == 2) return parts.pop().split(";").shift(); 
} 

Это тестовый файл (я удалил большую часть кода, так как он не работает в любом случае, я чеканка свой собственный хвост здесь):

describe('forge.communications.CommsApp', function() { 

    beforeEach(module('forge.communications.CommsApp')); 

    var route, rootScope, proxy, commsSignalrEventService; 

    beforeEach(inject(function (_$route_, _$rootScope_, _commsSignalrEventService_) { 
     route = _$route_, 
     rootScope = _$rootScope_; 
     commsSignalrEventService = _commsSignalrEventService_; 
    })); 

    describe("should map routes to controllers and templates", function() { 

     it("/scheduled-messages route should be mapped to ScheduledMessageListController", function() { 
      expect(2).toEqual(2); 
      expect(route.routes['/scheduled-messages'].controller).toBe('ScheduledMessageListController'); 
     }); 

    }); 
}); 

Это CommsSignalREventService.ts файл:

var servicesModule: ng.IModule = angular.module('forge.communications.services'); 

servicesModule.factory('commsSignalrEventService', function ($rootScope): CommsSignalrEventService { 
    return new CommsSignalrEventService($rootScope); 
}); 

class CommsSignalrEventService { 

private $rootScope: ng.IScope; 
private proxy:any = null; 

constructor($rootScope) { 
    this.$rootScope = $rootScope; 
} 

public initialize(): JQueryPromise<any>{ 

    this.proxy = $.connection['communicationsCenterHub']; 

    console.log('proxy',this.proxy); 

    //scheduled messages 
    this.proxy.client.broadcastScheduledMessageCreatedEvent = (messageId: number) => { 
     this.$rootScope.$broadcast('comms-message-created', { messageId: messageId }); 
    }; 

    this.proxy.client.broadcastScheduledMessageUpdatedEvent = (messageId: number) => { 
     this.$rootScope.$broadcast('comms-message-updated', { messageId: messageId }); 
    }; 

    this.proxy.client.broadcastScheduledMessageStateChangedEvent = (messageId: number) => { 
     this.$rootScope.$broadcast('comms-message-statechanged', { messageId: messageId }); 
    }; 

    this.proxy.client.broadcastScheduledMessageDeletedEvent = (messageId: number) => { 
     this.$rootScope.$broadcast('comms-message-deleted', { messageId: messageId }); 
    }; 

    //geotriggered messages 
    this.proxy.client.broadcastGeoMessageCreatedEvent = (messageId: number) => { 
     this.$rootScope.$broadcast('comms-geomessage-created', { messageId: messageId }); 
    }; 

    this.proxy.client.broadcastGeoMessageUpdatedEvent = (messageId: number) => { 
     this.$rootScope.$broadcast('comms-geomessage-updated', { messageId: messageId }); 
    }; 

    this.proxy.client.broadcastGeoMessageStateChangedEvent = (messageId: number) => { 
     this.$rootScope.$broadcast('comms-geomessage-statechanged', { messageId: messageId }); 
    }; 

    this.proxy.client.broadcastGeoMessageDeletedEvent = (messageId: number) => { 
     this.$rootScope.$broadcast('comms-geomessage-deleted', { messageId: messageId }); 
    }; 

    var promise = $.connection.hub.start(); 
    promise.done(function() { 
     //console.log('comms signalr hub started'); 
    }); 
    return promise; 
} 

    public RegisterScheduledMessageCreated(messageId: number): void{ 
     this.proxy.server.registerScheduledMessageCreated(messageId); 
    } 

    public RegisterScheduledMessageUpdated(messageId: number): void { 
     this.proxy.server.registerScheduledMessageUpdated(messageId); 
    } 

    public RegisterScheduledMessageDeleted(messageId: number): void { 
     this.proxy.server.registerScheduledMessageDeleted(messageId); 
    } 

    public RegisterScheduledMessageStateChanged(messageId: number): void { 
     this.proxy.server.registerScheduledMessageStateChanged(messageId); 
    } 

    public RegisterGeoMessageCreated(messageId: number): void { 
     this.proxy.server.registerGeoMessageCreated(messageId); 
    } 

    public RegisterGeoMessageUpdated(messageId: number): void { 
     this.proxy.server.registerGeoMessageUpdated(messageId); 
    } 

    public RegisterGeoMessageDeleted(messageId: number): void { 
     this.proxy.server.registerGeoMessageDeleted(messageId); 
    } 

    public RegisterGeoMessageStateChanged(messageId: number): void { 
     this.proxy.server.registerGeoMessageStateChanged(messageId); 
    } 
} 

ошибка Я постоянно вижу в командной строке, когда я бег кармы, это forge.communications.CommsApp столкнулся с разл бъявлению исключение FAILED TypeError: Не удается прочитать свойство «клиента» неопределенных в CommsSignalREventService, а это означает, что «прокси» переменная в файле CommsSignalREventService.ts не определено:

this.proxy = $.connection['communicationsCenterHub']; 
console.log('proxy', this.proxy); //resolves to UNDEFINED in tests, works fine in the app 

this.proxy.client.broadcastScheduledMessageCreatedEvent = function (messageId) { 
     _this.$rootScope.$broadcast('comms-message-created', { messageId: messageId }); 
    }; 

Я буду признателен за любую помощь, потому что количество времени На этом этапе я попытался понять, что это смехотворно.

ответ

3

Я думаю, ваша проблема в том, что ваше фактическое приложение ссылается на JavaScript, динамически генерируемый SignalR во время выполнения. Этот скрипт обычно находится в «~/signalr/hubs» или «~/signalr/js».

Этот сценарий создает для вас $.connection['communicationsCenterHub'] прокси. Без ссылки на этот скрипт в вашем тесте этот прокси будет undefined.

Я предполагаю, что вы не используете сервер SignalR при запуске тестов Jasmine. Если это так у вас есть два варианта:

  1. Вы можете просто скопировать скрипт, генерируемый SignalR в «~/signalr/концентраторы» в файл и ссылки, что в ваших тестах. Вы можете вручную сделать это, указав свой браузер на сгенерированный URL-адрес сценария и, но вам придется обновлять этот файл в любое время, когда ваш концентратор изменится. Вы можете automate this, запустив signalr.exe ghp /path:[path to the .dll that contains your Hub class] в качестве этапа после сборки, который сгенерирует этот файл для вас.

  2. Вы можете просто не использовать сгенерированный прокси вообще. Посмотрите раздел «Без сгенерированного прокси» в SignalR JS API reference.

+0

Спасибо, копируя сгенерированный скрипт в отдельный файл и ссылаясь на него в karma.conf.js, решил мою проблему. Я попытаюсь применить шаг после сборки позже. – codeepic