Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Karma+Mocha+React Cannot convert a Symbol value to a string

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;
like image 910
pratyush jha Avatar asked Jan 08 '16 12:01

pratyush jha


3 Answers

Your tests probably have found a mismatch comparing 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.

like image 134
Ricardo Stuven Avatar answered Nov 09 '22 17:11

Ricardo Stuven


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

like image 5
Manu Avatar answered Nov 09 '22 18:11

Manu


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.

like image 3
Cory Z A Avatar answered Nov 09 '22 18:11

Cory Z A