由于套接字 io 不存在而导致测试失败

Posted

技术标签:

【中文标题】由于套接字 io 不存在而导致测试失败【英文标题】:Tests Failing due to socket io does not exist 【发布时间】:2013-09-26 20:58:54 【问题描述】:

io 使用我自己的 Angular 服务。我正在使用 yeoman 和 angular 工作流程:http://yeoman.io/ 我需要让 io 被 karma 识别,这样测试才不会失败?

'use strict';

angular.module('publicApp')
    .factory('socket', function ($rootScope) 
    var socket = io.connect();

    return 
        on: function on(eventName, callback) 
            socket.on(eventName, function () 
                var args = arguments;
                $rootScope.$apply(function () 
                    callback.apply(socket, args);
                );
            );
        ,
        emit: function emit(eventName, data, callback) 
            socket.emit(eventName, data, function () 
                var args = arguments;
                $rootScope.$apply(function () 
                    if (callback) 
                        callback.apply(socket, args);
                    
                );
            );
        
    ;
);

angular.module('publicApp')
    .controller('MainCtrl', function ($scope, socket) 
    $scope.awesomeThings = [
        'html5 Boilerplate',
        'AngularJS',
        'Karma'];
    socket.on('person:added', function (data) 
        $scope.person = data;
    );
);
angular.module('publicApp', [])
    .config(function ($routeProvider) 
    $routeProvider.when('/', 
        templateUrl: 'views/main.html',
        controller: 'MainCtrl'
    )
        .otherwise(
        redirectTo: '/'
    );
);
'use strict';

describe('Controller: MainCtrl', function () 

    // load the controller's module
    beforeEach(module('publicApp'));

    var MainCtrl,
    scope;

    // Initialize the controller and a mock scope
    beforeEach(inject(function ($controller, $rootScope) 
        scope = $rootScope.$new();
        MainCtrl = $controller('MainCtrl', 
            $scope: scope
        );
    ));

    it('should attach a list of awesomeThings to the scope', function () 
        expect(scope.awesomeThings.length).toBe(3);
    );
);

io 是窗口的一部分,我尝试使用 angulars $window 对象但没有运气。我从业力得到的错误是:

Running "karma:unit" (karma) task
WARN [karma]: Port 8080 in use
INFO [karma]: Karma v0.10.2 server started at http://localhost:8081/
INFO [launcher]: Starting browser Chrome
WARN [watcher]: Pattern "/Users/michaeljames/Documents/Projects/***/public/test/mock/**/*.js" does not match any file.
INFO [Chrome 29.0.1547 (Mac OS X 10.8.2)]: Connected on socket LmbsWIC-97zMEi76FmiE
Chrome 29.0.1547 (Mac OS X 10.8.2) Controller: MainCtrl should attach a list of awesomeThings to the scope FAILED
    ReferenceError: io is not defined
        at Object.$get (/Users/michaeljames/Documents/Projects/***/public/app/scripts/services/socket.js:5:16)
        at Object.invoke (/Users/michaeljames/Documents/Projects/***/public/app/bower_components/angular/angular.js:3000:28)
        at /Users/michaeljames/Documents/Projects/***/public/app/bower_components/angular/angular.js:2838:37
        at getService (/Users/michaeljames/Documents/Projects/***/public/app/bower_components/angular/angular.js:2960:39)
        at invoke (/Users/michaeljames/Documents/Projects/***/public/app/bower_components/angular/angular.js:2978:13)
        at Object.instantiate (/Users/michaeljames/Documents/Projects/***/public/app/bower_components/angular/angular.js:3012:23)
        at /Users/michaeljames/Documents/Projects/***/public/app/bower_components/angular/angular.js:4981:24
        at null.<anonymous> (/Users/michaeljames/Documents/Projects/***/public/test/spec/controllers/main.js:14:16)
        at Object.invoke (/Users/michaeljames/Documents/Projects/***/public/app/bower_components/angular/angular.js:3000:28)
        at workFn (/Users/michaeljames/Documents/Projects/***/public/app/bower_components/angular-mocks/angular-mocks.js:1795:20)
    Error: Declaration Location
        at window.jasmine.window.inject.angular.mock.inject (/Users/michaeljames/Documents/Projects/***/public/app/bower_components/angular-mocks/angular-mocks.js:1781:25)
        at null.<anonymous> (/Users/michaeljames/Documents/Projects/***/public/test/spec/controllers/main.js:12:14)
        at /Users/michaeljames/Documents/Projects/***/public/test/spec/controllers/main.js:3:1
    TypeError: Cannot read property 'length' of undefined
        at null.<anonymous> (/Users/michaeljames/Documents/Projects/***/public/test/spec/controllers/main.js:20:31)
Chrome 29.0.1547 (Mac OS X 10.8.2): Executed 1 of 1 (1 FAILED) ERROR (0.306 secs / 0.067 secs)
Warning: Task "karma:unit" failed. Use --force to continue.

Aborted due to warnings.

【问题讨论】:

您是否在 karma conf.js 文件中引用了套接字 io? 文件“/socket.io/socket.io.js”一般由节点服务器动态生成。您可以下载它,存储本地版本,并在 karma.conf.js 的“文件”数组中添加对它的引用 标记你的权利,我需要忽略 io。但是我在 karma conf 文件中的哪个位置执行此操作?我正在获取脚本,因为我强制它编译到 dist 文件夹并可以看到脚本文件。干杯, @MathieuLescure 我已将以下内容添加到我的 karma.conf 和 karma.e2e.conf.. 文件的文件数组中:['app/bower_components/socket.io/socket.io.js ']。我仍然没有定义 io... 【参考方案1】:

我会模拟整个套接字服务,因为这是一种访问某种服务器的方法,而这些单元测试应该只测试你的 UI 代码(在 ngMock 中使用 $httpBackend 的原因)。

这里有一些聪明的人想出来了: https://github.com/btford/angular-socket-io-seed/issues/4#issuecomment-14505212.

【讨论】:

谢谢!这是有道理的。 Btford - 他知道他的东西。我会给这个打勾,但它缺乏细节。【参考方案2】:

在您的 karma.config.js 文件部分中注入服务器端 socket.io.js

files: [
  'test/unit/**/*.js',
  'any/other/included/files/*.js',
  'http://localhost:8080/socket.io/socket.io.js'   //just only inject it
],

【讨论】:

如果您不想模拟并经历所有麻烦,此解决方案可以正常工作。

以上是关于由于套接字 io 不存在而导致测试失败的主要内容,如果未能解决你的问题,请参考以下文章

selenium+java 元素有时存在 有时不存在,怎么处理

Python如果导出失败,pass函数功能

Bash:如何测试 mkdir 命令失败?

Spark2.4.3 中方法不存在错误导致重新分区失败

SQL Db2 中的左连接而不是不存在

文件上传失败,原因99611文件不存在