错误:Karma + RequireJS + Jasmine中的匿名定义不匹配。

8

我已经卡在这里一段时间,试图设置和运行单元测试。

我有一个使用RequireJS和r.js进行优化的AngularJS前端,因此它全部都在一个单独的文件中。这很好用!

但是无法执行单元测试。目前还没有什么花哨的东西,只是从教程中复制了一个入门程序。

tests/user/user.test.js:

define(['angular', 'angular-mocks', 'app'], function(angular, app) {
  describe('Unit: UserController', function() {
    beforeEach(module('user.app'));

    it('should do something', function() {
      console.log('did it');
    });
  });
});

然后我有一个karma.conf.js文件:

module.exports = function(config) {
  config.set({
    logLevel: config.LOG_DEBUG,
    basePath: './',

    files: [
      // r.js'd app files
      {pattern: 'dist/app.js', included: false},
      // the tests
      {pattern: 'tests/**/*.test.js', included: true},
    ],

    excluded: ['tests/main.test.js']

    frameworks: ['jasmine', 'requirejs'],

    browsers: ['PhantomJS'],

    plugins: [
      'karma-jasmine',
      'karma-junit-reporter',
      'karma-phantomjs-launcher',
      'karma-requirejs'
    ],

  });
};

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

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

Object.keys(window.__karma__.files).forEach(function(file) {
  if (TEST_REGEXP.test(file)) {
    // Normalize paths to RequireJS module names.
    allTestFiles.push(pathToModule(file));
  }
});

require.config({
  baseUrl: '/base',

  paths: {
    'angular-mocks': 'node_modules/angular-mocks/angular-mocks',
    'app': 'dist/app',
  },

  deps: allTestFiles,

  callback: function() {
    console.log('load complete');
    window.__karma__.start();
  },
});

最后是一个 gulp 任务:

var gulp  = require('gulp');
var karma = require('karma').server;

gulp.task('unit-test', function(done) {
  karma.start({
    configFile: __dirname + '/karma.conf.js',
      singleRun: true
   }, function() { done(); });
}

我在一些地方添加了日志输出,显示文件已加载。

但是我卡在了获取 tests/user/user.test.js 中的 Error: Mismatched anonymous define() 上,我不知道哪里出错了。以下是输出结果:http://pastebin.com/evJPj9B3

如果我像这样命名单元测试模块

define('namedtestorso', ['angular', 'angular-mocks', 'app'], function(angular, app) {
  ...

我不再收到任何错误提示,但测试也未被执行。由于我能想到的所有示例都将其用作匿名定义,因此我认为这里的命名不正确。但在这种情况下,日志输出会被执行,显示来自main.test.js的配置回调被执行了两次。(这是什么提示吗?)

如果有人有想法如何修复/运行它,甚至如何继续找出问题所在,那将是很棒的。提前感谢!

2个回答

11

我现在已经使它运行起来了,以下是我的解决方案:

我认为我现在对 karma 的工作原理有了更好的理解(如果我错了,请告诉我),所以我找到了我需要做的事情。

看起来所有的问题都在于将文件放入 karma.conf.js 中,以便它们可供 main.test.js 加载。否则,它们就处于“上下文”之外,无法访问。但是,当把它们放进去时,请确保将 included 标志设置为 false

karma.conf.js 的更改:

files: [
  ...
  // Also included these dependencies. All the others are minified in the
  // app.js but if you don't do that, also include all project deps like
  // AngularJS etc.
  { pattern: 'node_modules/jasmine-core/lib/jasmine-core/boot.js', included: false },
  { pattern: 'node_modules/angular-mocks/angular-mocks.js', included: false},

  // Then I had an error in my pattern ('tests/**/*.test.js')
  // Only the `main.test.js` is supposed to be included!
  { pattern: 'tests/user/user.test.js', included: false }
  { pattern: 'tests/main.test.js', included: true }
  ...

如果我没记错的话,Karma会生成一个HTML文件,并且在使用included:true标签时会通过脚本标签进行加载。因此,如果使用RequireJS,将include设置为false非常重要,否则会出现Error:Mismatched anonymous define()错误。所以现在这对我来说是有意义的。
解决了这个问题后,还有其他模块未找到的问题。因为我使用了RequireJS优化器,所以必须将所有模块“映射”到主app.js文件上,这样当测试JS文件需要某个模块时,RequireJS就可以确保它已经加载或者正在加载。
因此,最终我修改了main.test.js中的paths部分:
paths: {
  // Added these for example
  'angular': '../dist/app',
  'angular-ui-router': '../dist/app',
  // (and also my project modules)
  ...

没错,这似乎有点“hacky”。与此同时,在解决这个问题后,我也改变了我的工作流程,运行开发文件上的单元测试,并依赖其他工具正常工作(如果有问题,e2e测试会捕捉到)。

希望能对处于我这种情况的人有所帮助!


1

如果你访问requirejs网站,当你在HTML中包含任何脚本标签时,你会看到这个错误。这意味着由karma提供的HTML

因此,在karma.conf.js中,当你像这样包含文件时: files['/base/src/scripts/xyz.js'] 我认为它被添加为一个脚本标签,并且你一直得到 Error: Mismatched anonymous define() module

尝试模式示例:{pattern: '/base/src/scripts/xyz.js', included: false} 这可以防止将js添加到脚本标签中


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接