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

javascript - Karma+Mocha+React Cannot convert a Symbol value to a string - Stack Overflow

programmeradmin3浏览0评论

I am using webpack+babel for a React+Redux app and Mocha+Karma for testing. The redux test cases are getting executed properly. However, when I try to do DOM testing using react-addons-test-utils and running it with Karma it gives this error

Uncaught TypeError: Cannot convert a Symbol value to a string at http://localhost:9876/karma.js:339

In order to debug it properly I put a couple of loggers in karma lib files( I know I shouldn't have) and got this

Karma Error for React DOM testing

However, when I do not use KarmaJS and simply try to run the tests, it seems fine. Here is my karma.conf

"use strict";
let webpackConfig = require('./webpack.config');
const coverage = process.env.COVERAGE;

webpackConfig.externals = {};

getWebpackLoaders();

module.exports = function(config){
  config.set({
    basePath: '.',
    frameworks:['mocha'],
    autoWatchBatchDelay:500,
    browsers: ['Chrome'],
    customLaunchers: {
      Chrome_without_security: {
        base: 'Chrome',
        flags: ['--disable-web-security']
      }
    },
    preprocessors: {
      './test/**/*.js':['webpack']
    },
    reporters: getReporters(),
    coverageReporter: {
      reporters: [
        {type: 'lcov', dir: 'coverage/', subdir: '.'},
        {type: 'json', dir: 'coverage/', subdir: '.'},
        {type: 'text-summary'}
      ]
    },
    exclude:['node_modules'],
    port:9876,

    files: [
      'node_modules/react/dist/react-with-addons.js',
      'test/test.js'
    ],
    webpack:webpackConfig,
    plugins: [
      'karma-webpack',
      'karma-mocha',
      'karma-coverage',
      'karma-chrome-launcher'
    ]
  })
};

function getWebpackLoaders(){
  if(coverage){
    let loaders  = webpackConfig.module.loaders;
    let jsLoader = loaders[1];
    jsLoader.exclude = /node_modules|\.test\.js$/ //exclude both node_modules and test
    loaders.push({
      test:/\.test\.js$/,
      loaders:['babel-loader']
    });
    loaders.push({
      test: /\.js$/,
      loaders: ['isparta'],
      exclude: /node_modules|\.test.js$/ // exclude node_modules and test files
    })
  }
}

function getReporters() {
  var reps = ['progress'];
  if (coverage) {
    reps.push('coverage');
  }
  return reps;
}

EDIT 1. Adding webpack.config to this

var webpack = require('webpack');
var argv = require('minimist')(process.argv.slice(2));

var DEBUG = !argv.release;

var AUTOPREFIXER_LOADER = 'autoprefixer-loader?{browsers:[' +
  '"Android >= 4", "Chrome >= 20", "Firefox >= 24", ' +
  '"Explorer >= 9", "iOS >= 6", "Safari >= 6"]}';

var GLOBALS = {
  'process.env.NODE_ENV': DEBUG ? '"development"' : '"production"',
  '__DEV__': DEBUG
};

var config = {

  entry: './app.js',

  output: {
    filename: 'app.js',
    path: './build/',
    publicPath: './',
    sourcePrefix: '  '
  },

  externals: {
    react: 'React'
  },

  cache: DEBUG,
  debug: DEBUG,
  devtool: DEBUG ? '#inline-source-map' : false,

  stats: {
    colors: true,
    reasons: DEBUG
  },

  plugins: [
    new webpack.optimize.OccurenceOrderPlugin(),
    new webpack.DefinePlugin(GLOBALS)
  ].concat(DEBUG ? [] : [
    new webpack.optimize.DedupePlugin(),
    new webpack.optimize.UglifyJsPlugin(),
    new webpack.optimize.AggressiveMergingPlugin()
  ]),

  resolve: {
    extensions: ['', '.webpack.js', '.js', '.jsx']
  },

  module: {
    preLoaders: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
        loader: 'eslint-loader'
      }
    ],

    loaders: [
      {
        test: /\.less$/,
        loader: 'style-loader!css-loader!' + AUTOPREFIXER_LOADER + '!less-loader'
      },
      {
        test: /\.jsx?$/,
        exclude: /node_modules/,
        loader: 'babel-loader'
      },
      {
        test: /\.json$/,
        exclude: /node_modules/,
        loader: 'json-loader'
      }
    ]
  }
};

module.exports = config;

I am using webpack+babel for a React+Redux app and Mocha+Karma for testing. The redux test cases are getting executed properly. However, when I try to do DOM testing using react-addons-test-utils and running it with Karma it gives this error

Uncaught TypeError: Cannot convert a Symbol value to a string at http://localhost:9876/karma.js:339

In order to debug it properly I put a couple of loggers in karma lib files( I know I shouldn't have) and got this

Karma Error for React DOM testing

However, when I do not use KarmaJS and simply try to run the tests, it seems fine. Here is my karma.conf

"use strict";
let webpackConfig = require('./webpack.config');
const coverage = process.env.COVERAGE;

webpackConfig.externals = {};

getWebpackLoaders();

module.exports = function(config){
  config.set({
    basePath: '.',
    frameworks:['mocha'],
    autoWatchBatchDelay:500,
    browsers: ['Chrome'],
    customLaunchers: {
      Chrome_without_security: {
        base: 'Chrome',
        flags: ['--disable-web-security']
      }
    },
    preprocessors: {
      './test/**/*.js':['webpack']
    },
    reporters: getReporters(),
    coverageReporter: {
      reporters: [
        {type: 'lcov', dir: 'coverage/', subdir: '.'},
        {type: 'json', dir: 'coverage/', subdir: '.'},
        {type: 'text-summary'}
      ]
    },
    exclude:['node_modules'],
    port:9876,

    files: [
      'node_modules/react/dist/react-with-addons.js',
      'test/test.js'
    ],
    webpack:webpackConfig,
    plugins: [
      'karma-webpack',
      'karma-mocha',
      'karma-coverage',
      'karma-chrome-launcher'
    ]
  })
};

function getWebpackLoaders(){
  if(coverage){
    let loaders  = webpackConfig.module.loaders;
    let jsLoader = loaders[1];
    jsLoader.exclude = /node_modules|\.test\.js$/ //exclude both node_modules and test
    loaders.push({
      test:/\.test\.js$/,
      loaders:['babel-loader']
    });
    loaders.push({
      test: /\.js$/,
      loaders: ['isparta'],
      exclude: /node_modules|\.test.js$/ // exclude node_modules and test files
    })
  }
}

function getReporters() {
  var reps = ['progress'];
  if (coverage) {
    reps.push('coverage');
  }
  return reps;
}

EDIT 1. Adding webpack.config to this

var webpack = require('webpack');
var argv = require('minimist')(process.argv.slice(2));

var DEBUG = !argv.release;

var AUTOPREFIXER_LOADER = 'autoprefixer-loader?{browsers:[' +
  '"Android >= 4", "Chrome >= 20", "Firefox >= 24", ' +
  '"Explorer >= 9", "iOS >= 6", "Safari >= 6"]}';

var GLOBALS = {
  'process.env.NODE_ENV': DEBUG ? '"development"' : '"production"',
  '__DEV__': DEBUG
};

var config = {

  entry: './app.js',

  output: {
    filename: 'app.js',
    path: './build/',
    publicPath: './',
    sourcePrefix: '  '
  },

  externals: {
    react: 'React'
  },

  cache: DEBUG,
  debug: DEBUG,
  devtool: DEBUG ? '#inline-source-map' : false,

  stats: {
    colors: true,
    reasons: DEBUG
  },

  plugins: [
    new webpack.optimize.OccurenceOrderPlugin(),
    new webpack.DefinePlugin(GLOBALS)
  ].concat(DEBUG ? [] : [
    new webpack.optimize.DedupePlugin(),
    new webpack.optimize.UglifyJsPlugin(),
    new webpack.optimize.AggressiveMergingPlugin()
  ]),

  resolve: {
    extensions: ['', '.webpack.js', '.js', '.jsx']
  },

  module: {
    preLoaders: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
        loader: 'eslint-loader'
      }
    ],

    loaders: [
      {
        test: /\.less$/,
        loader: 'style-loader!css-loader!' + AUTOPREFIXER_LOADER + '!less-loader'
      },
      {
        test: /\.jsx?$/,
        exclude: /node_modules/,
        loader: 'babel-loader'
      },
      {
        test: /\.json$/,
        exclude: /node_modules/,
        loader: 'json-loader'
      }
    ]
  }
};

module.exports = config;
Share Improve this question edited Jan 8, 2016 at 15:02 pratyush jha asked Jan 8, 2016 at 12:13 pratyush jhapratyush jha 1431 gold badge2 silver badges7 bronze badges 2
  • 1 You're mixing ES5 and ES6, is the config file getting transpiled as well? – Henrik Andersson Commented Jan 8, 2016 at 12:16
  • What's in your webpack.config? – N3dst4 Commented Jan 8, 2016 at 14:35
Add a ment  | 

3 Answers 3

Reset to default 5

Your tests probably have found a mismatch paring React elements, but Mocha can't convert to string an internal Symbol property.

Try editing the file node_modules/mocha/lib/utils.js around line 602 in the function canonicalize and replace:

default:
  canonicalizedObj = value + '';

by

default:
  canonicalizedObj = String(value);

Then, run your tests again. This time, Mocha should be able to show you what went wrong.

Make sure you're not trying to console.log the result of getRenderOutput. This was the issue in my case.

I just ran into this problem as well using the exact same stack.

If your using TestUtils' shallowRenderer and following Redux's docs examples you'll most likely run into this when you try to log the output. Stringify the output, (JSON.stringify, etc) to solve the issue.

@Ricado Stuven's answer: Mocha has updated that line to value.toString(). Atleast for the lastest version as of this posts date (v2.3.4).

Post your a sample of your test file where it fails if this isn't it. Cheers.

发布评论

评论列表(0)

  1. 暂无评论