Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angularjs/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Angularjs 如何用Angular和Jasmine模拟socket.io_Angularjs_Socket.io_Jasmine_Angular Mock - Fatal编程技术网

Angularjs 如何用Angular和Jasmine模拟socket.io

Angularjs 如何用Angular和Jasmine模拟socket.io,angularjs,socket.io,jasmine,angular-mock,Angularjs,Socket.io,Jasmine,Angular Mock,我很难弄清楚如何在使用Jasmine和Karma的角度应用程序中正确模拟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/angu

我很难弄清楚如何在使用Jasmine和Karma的角度应用程序中正确模拟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.emit
,但不知道如何调用

任何帮助都将不胜感激

编辑:如果可能的话,我想使用,但我很难弄清楚它到底是如何工作的。

我会使用它来创建一个模拟套接字对象

例如,在每个之前的
中,将套接字初始化为空对象:

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');
你需要这些包裹和包裹。同样,如果你正在使用业力,它将需要。您可以在相应页面上找到有关设置的更多指南

编辑:在您的情况下,模拟需要每次都有
打开
发出
功能,因为控制器需要这些功能。在这种情况下,最好在每个
函数之前将其放入

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

我最终使用了中定义的
sockMock
对象。

Ah,这很有意义。两个问题:你有没有理由建议使用Sinon的
spy
功能与Jasmine的功能?另外,我添加的编辑是否会影响您的建议?您需要创建一个链接,将其作为依赖项传递给控制器,然后在测试后确认emits散列包含一些内容。就我个人而言,我更喜欢使用sinon。在这种情况下,我使用了一个间谍,因为我只需要知道是否有一吨被调用。如果您希望它调用回调(例如针对事件),则应使用
sinon.stub().callsArgWith(0,mockData)
。事实上,我没有用过茉莉花的间谍,我想这也行。