[英]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');
您將需要軟件包sinon和jasmine-sinon 。 另外,如果您使用的是Karma,則需要karma-sinon 。 您可以在相應頁面上找到有關設置的更多准則。
編輯:在你的情況你的模擬需要有on
和emit
功能,每一次,因為它們是由控制器所需。 在這種情況下,最好將其放入beforeEach
函數中:
socket = {
emit : sinon.spy(),
on : sinon.spy()
};
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.