最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - "Uncaught TypeError: Cannot read property '...' of null" using RequireJS with Kar

programmeradmin2浏览0评论

I'm trying to get Jasmine tests running in Karma. This is for an AngularJS app using RequireJS, but for now, the test is a simple expect(true).toBe(true); test with no Angular dependencies. I've found that it runs when I disable Karma's requirejs module and ment-out "client/app/require-shared.js" and "test/require-test.js" in files and load the testSpec.js file directly.

However, as soon as I re-enable requirejs and add the RequireJS config files back to karma.conf.js's files--keeping the testSpec.js file there to be loaded "statically"--I see the errors

Chrome 33.0.1750 (Windows 7) ERROR
  Uncaught TypeError: Cannot read property 'failedCount' of null
  at C:/.../project/node_modules/karma-jasmine/lib/adapter.js:126
Chrome 33.0.1750 (Windows 7) ERROR
  Uncaught TypeError: Cannot read property 'length' of null
  at C:/.../project/node_modules/karma-jasmine/lib/jasmine.js:2518
Chrome 33.0.1750 (Windows 7): Executed 1 of 2 ERROR (0.009 secs / 0.001 secs)

If I try the full Angular test, I get errors about $injector being null, but I think it's all rooted in this requirejs module issue. What am I missing in my setup to make this work?

test/karma.conf.js

module.exports = function(config) {

    config.set({
        basePath: "../", // resolves to "project/"

        frameworks: ["jasmine", "requirejs"],

        files: [
            // load the RequireJS config files first
            "client/app/require-shared.js",
            "test/require-test.js",

            // set included to false for files to be loaded via RequireJS
//          {pattern: "bower_ponents/**/*.js", included: false},
//          {pattern: "client/**/*.js",           included: false},
//          {pattern: "test/unit/*Spec.js",       included: false}
            {pattern: "test/unit/*Spec.js"}
        ],


        // list of files to exclude
        exclude: [
//          "client/app/app.js",
//          "client/app/bootstrap.js",
//          "client/app/require-main.js",
            "*.conf.js"
        ],

        reporters: ["progress"],
        port: 9876,
        colors: true,
        logLevel: config.LOG_INFO,
        autoWatch: false,
        browsers: ["Chrome"],
        singleRun: true
    });
};

client/app/require-shared.js

requirejs.config({
    paths: {
        "app":            "../app/app",
        "angular":        "../extlibs/angular-1.2.14",
        "jquery":         "../extlibs/jquery-2.1.0.min",
        "ng-cookies":     "../extlibs/AngularPlugins/angular-cookies-1.2.13",
        "ng-resource":    "../extlibs/AngularPlugins/angular-resource-1.2.13",
        "ng-route":       "../extlibs/AngularPlugins/angular-route-1.2.14",
    }

    ,shim: {
        angular: {
            exports: "angular"
        }
        ,"ng-resource": {
            deps: [ "angular" ],
            exports: "ng-resource"
        },
        ,"ng-cookies":     ["angular"]
        ,"ng-route":       ["angular"]
        ,"ngui-bootstrap": ["angular"]
    }
});

test/require-test.js

var allTestFiles = [];
var TEST_REGEXP = /(spec|test)\.js$/i;

var pathToModule = function(path) {
    return path.replace(/^\/base\//, "").replace(/\.js$/, "");
};

Object.keys(window.__karma__.files).forEach(function(file) {
    if (TEST_REGEXP.test(file)) {
        // Normalize paths to RequireJS module names.
        var normalPath = pathToModule(file);
        console.log("adding " + file + " as " + normalPath + " to allTestFiles array");
        allTestFiles.push(normalPath);
    }
});

requirejs.config({
    baseUrl: "/base/client/ponents/"

    /*
     * "path" is defined in require-shared.js and shared with
     * require-main. Add paths for the testing files.
     */
    ,paths: {
        "test":          "../../test",
        "bower":         "../../bower_ponents",
        "angular-mocks": "bower/angular-mocks/angular-mocks"
    }

    ,shim: {
        'angular-mocks': {
            deps: [ 'ng-resource' ],
            exports: 'angular.mock'
        }
    }

    ,deps: allTestFiles
    ,callback: window.__karma__.start
});

test/unit/testSpec.js

describe('a basic test of version', function() {
    it('true should be true', function() {
        expect(true).toBe(true);
    });
});

I'm trying to get Jasmine tests running in Karma. This is for an AngularJS app using RequireJS, but for now, the test is a simple expect(true).toBe(true); test with no Angular dependencies. I've found that it runs when I disable Karma's requirejs module and ment-out "client/app/require-shared.js" and "test/require-test.js" in files and load the testSpec.js file directly.

However, as soon as I re-enable requirejs and add the RequireJS config files back to karma.conf.js's files--keeping the testSpec.js file there to be loaded "statically"--I see the errors

Chrome 33.0.1750 (Windows 7) ERROR
  Uncaught TypeError: Cannot read property 'failedCount' of null
  at C:/.../project/node_modules/karma-jasmine/lib/adapter.js:126
Chrome 33.0.1750 (Windows 7) ERROR
  Uncaught TypeError: Cannot read property 'length' of null
  at C:/.../project/node_modules/karma-jasmine/lib/jasmine.js:2518
Chrome 33.0.1750 (Windows 7): Executed 1 of 2 ERROR (0.009 secs / 0.001 secs)

If I try the full Angular test, I get errors about $injector being null, but I think it's all rooted in this requirejs module issue. What am I missing in my setup to make this work?

test/karma.conf.js

module.exports = function(config) {

    config.set({
        basePath: "../", // resolves to "project/"

        frameworks: ["jasmine", "requirejs"],

        files: [
            // load the RequireJS config files first
            "client/app/require-shared.js",
            "test/require-test.js",

            // set included to false for files to be loaded via RequireJS
//          {pattern: "bower_ponents/**/*.js", included: false},
//          {pattern: "client/**/*.js",           included: false},
//          {pattern: "test/unit/*Spec.js",       included: false}
            {pattern: "test/unit/*Spec.js"}
        ],


        // list of files to exclude
        exclude: [
//          "client/app/app.js",
//          "client/app/bootstrap.js",
//          "client/app/require-main.js",
            "*.conf.js"
        ],

        reporters: ["progress"],
        port: 9876,
        colors: true,
        logLevel: config.LOG_INFO,
        autoWatch: false,
        browsers: ["Chrome"],
        singleRun: true
    });
};

client/app/require-shared.js

requirejs.config({
    paths: {
        "app":            "../app/app",
        "angular":        "../extlibs/angular-1.2.14",
        "jquery":         "../extlibs/jquery-2.1.0.min",
        "ng-cookies":     "../extlibs/AngularPlugins/angular-cookies-1.2.13",
        "ng-resource":    "../extlibs/AngularPlugins/angular-resource-1.2.13",
        "ng-route":       "../extlibs/AngularPlugins/angular-route-1.2.14",
    }

    ,shim: {
        angular: {
            exports: "angular"
        }
        ,"ng-resource": {
            deps: [ "angular" ],
            exports: "ng-resource"
        },
        ,"ng-cookies":     ["angular"]
        ,"ng-route":       ["angular"]
        ,"ngui-bootstrap": ["angular"]
    }
});

test/require-test.js

var allTestFiles = [];
var TEST_REGEXP = /(spec|test)\.js$/i;

var pathToModule = function(path) {
    return path.replace(/^\/base\//, "").replace(/\.js$/, "");
};

Object.keys(window.__karma__.files).forEach(function(file) {
    if (TEST_REGEXP.test(file)) {
        // Normalize paths to RequireJS module names.
        var normalPath = pathToModule(file);
        console.log("adding " + file + " as " + normalPath + " to allTestFiles array");
        allTestFiles.push(normalPath);
    }
});

requirejs.config({
    baseUrl: "/base/client/ponents/"

    /*
     * "path" is defined in require-shared.js and shared with
     * require-main. Add paths for the testing files.
     */
    ,paths: {
        "test":          "../../test",
        "bower":         "../../bower_ponents",
        "angular-mocks": "bower/angular-mocks/angular-mocks"
    }

    ,shim: {
        'angular-mocks': {
            deps: [ 'ng-resource' ],
            exports: 'angular.mock'
        }
    }

    ,deps: allTestFiles
    ,callback: window.__karma__.start
});

test/unit/testSpec.js

describe('a basic test of version', function() {
    it('true should be true', function() {
        expect(true).toBe(true);
    });
});
Share Improve this question asked Apr 7, 2014 at 15:22 nshew13nshew13 3,0975 gold badges26 silver badges40 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 3

The problem was that the TEST_REGEXP generated by karma init looked for either spec or test in the filename. This resulted in the require-test.js file getting pulled in as a test specification.

The solution is one of

  • rename require-test.js
  • change (spec|test) to just spec in the RE
  • change the RE to /^(?:(?!require-test\.js$).)*(spec|test)\.js$/i (see also, this answer)

This could also be the cause of your problem as it reports the same error under alternate circumstances (missing package.json): https://github./tkellen/js-matchdep/issues/11. However, if you are seeing this error message with this oute, then you're running an older version of npm. Upgrading will give you a different error message (according to the thread).

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论