簡體   English   中英

如何使用Angular和Jasmine模擬socket.io

[英]How to mock socket.io with Angular and Jasmine

我在弄清楚如何使用Jasmine和Karma在Angular應用程序中正確模擬Socket.io時遇到麻煩。

以下是在karma.conf.js找到的文件:

'bower_components/angular/angular.js',
'bower_components/angular-mocks/angular-mocks.js',
'bower_components/angular-ui-router/release/angular-ui-router.js',
'bower_components/angular-socket-io/socket.js',
'bower_components/socket.io-client/socket.io.js',
'bower_components/angular-socket-io/mock/socket-io.js',
'public/javascripts/*.js',
'ng_tests/**/*.js',
'ng_tests/stateMock.js'

這是我的控制器的外觀:

var lunchrControllers = angular.module('lunchrControllers', []);

lunchrControllers.controller('UserMatchingController', ['$state', 'socket',
    function ($state, socket) {
        socket.emit('match');

        socket.on('matched', function (data) {
            $state.go('users.matched', {name: data.name})
        });
    }]);

這是我的插座工廠:

var lunchrFactories = angular.module('lunchrFactories', []);

lunchrFactories.factory('socket', function (socketFactory) {
    return socketFactory();
});

這是主要的角度模塊:

var lunchrApp = angular.module('lunchr', ['ui.router', 'btford.socket-io', 'lunchrControllers', 'lunchrFactories' ]);

lunchrApp.config(['$stateProvider', '$urlRouterProvider', '$locationProvider',
    function ($stateProvider, $urlRouterProvider, $locationProvider) {
        $urlRouterProvider.otherwise('/');

        $stateProvider.
            state('mainPage', {
                url: '/',
                templateUrl: '/partials/main.jade',
                controller: 'MainPageController'
            })
            .state('users', {
                url: '/users',
                templateUrl: '/partials/users.jade',
                controller: 'UserController'
            })
            .state('users.matching', {
                url: '/matching',
                templateUrl: '/partials/users.matching.jade',
                controller: 'UserMatchingController'
            })
            .state('users.matched', {
                url: '/matched',
                templateUrl: '/partials/users.matched.jade',
                params:{name:null},
                controller: 'UserMatchedController'
            })
            .state('register', {
                url:'/register',
                templateUrl: 'partials/register.jade',
                controller: 'RegisterController'
            });
        $locationProvider.html5Mode(true);
    }]);

這是我無法弄清楚的測試:

'use strict';

describe('UserMatchingController', function () {
    beforeEach(module('lunchr'));
    beforeEach(module('stateMock'));


    var $controller, $rootScope, $state, socket;

    beforeEach(inject(function ($injector) {
        // Get hold of a scope (i.e. the root scope)
        $rootScope = $injector.get('$rootScope');

        $state = $injector.get('$state');

        // The $controller service is used to create instances of controllers
        $controller = $injector.get('$controller');

        socket = $injector('socket');
    }));

    afterEach(function () {
        $state.ensureAllTransitionsHappened();
    });

    function createController() {
        return $controller('UserMatchingController', {'$scope': $rootScope});
    }

    describe('on initiazation', function(){
        it('socket should emit a match', function() {
            createController();

            // would like to be able to expect a socket.emit call
        });
        it('should transition to users.matched upon receiving matched', function(){
            createController();
            $state.expectTransitionTo('user.matched');
            socket.receive('matched', {name: 'Ben'}); //This errors out with: cannot read property 'receive' of undefined
        })
    })
});

我懷疑socket未正確socket ,我不確定如何修復它。 同樣,我也希望能夠對socket.emit進行調用,但不知道如何進行。

任何幫助,將不勝感激。

編輯:如果可能的話,我想使用這個套接字模擬 ,但是我很難弄清楚它的工作方式。

我最終使用了此解決方案中定義的sockMock對象。

我將使用Sinon.js創建一個模擬套接字對象。

例如,在您的beforeEach ,將套接字初始化為空對象:

socket = {};

createController()必須將模擬傳遞給控制器​​:

$controller('UserMatchingController', {'$scope': $rootScope, 'socket': socket});

然后在您的測試中執行以下操作:

socket.emit = sinon.spy(); //Create a spy so we can check if it was called
createController();

expect(socket.emit).toHaveBeenCalledWith('match');

您將需要軟件包sinonjasmine-sinon 另外,如果您使用的是Karma,則需要karma-sinon 您可以在相應頁面上找到有關設置的更多准則。

編輯:在你的情況你的模擬需要有onemit功能,每一次,因為它們是由控制器所需。 在這種情況下,最好將其放入beforeEach函數中:

socket = {
  emit : sinon.spy(),
  on : sinon.spy()
};

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM