Jammer
Jammer

Reputation: 440

Typescript/Karma: Making CommonJS available to Karma during test runs

I'm trying to write unit tests in Typescript using Jasmine and running with Karma. I've read this tutorial and saw this question on SO, but my issue is persisting.

When the Typescript compiler compiles my typescript into javascript, it uses the require syntax to import definitions from other files. When I run my compiled tests, I get an error similar to this one:

Uncaught ReferenceError: require is not defined at calculator.spec.js

From this, I'm theorizing that nothing that would define the require syntax is available at the time of the execution of my spec. However, what I'm not clear on is what I should do about it. One SO question suggested the use of karma-browserify, but I noticed that the tutorial above managed to get this working without that. Any help anyone could provide would be appreciated.

Here are my files:

package.json

{
  "name": "karma-stuff",
  "version": "0.1.0",
  "description": "A thing that helps me test stuff",
  "main": "index.js",
  "scripts": {
    "test": "karma start"
  },
  "keywords": [
    "help"
  ],
  "author": "me",
  "license": "MIT",
  "devDependencies": {
    "jasmine": "^2.5.2",
    "karma": "^1.3.0",
    "karma-chrome-launcher": "^2.0.0",
    "karma-jasmine": "^1.0.2",
    "karma-typescript-preprocessor": "^0.3.0",
    "tsc": "^1.20150623.0"
  }
}

tsconfig.json

{
  "compilerOptions": {
    "target": "es5",
    "module": "commonjs",
    "moduleResolution": "node",
    "sourceMap": true,
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "removeComments": false,
    "noImplicitAny": false
  }
}

typings.json

{
  "globalDependencies": {
    "core-js": "registry:dt/core-js#0.0.0+20160725163759",
    "jasmine": "registry:dt/jasmine#2.5.0+20161003201800",
    "node": "registry:dt/node#6.0.0+20160909174046"
  }
}

karma.conf.js

module.exports = function(config) {
  config.set({
    basePath: '',
    frameworks: ['jasmine'],
    files: [
      '*.spec.ts'
    ],
    preprocessors: {
      '**/*.ts': ['typescript']
    },

    typescriptPreprocessor: {
      options: {
        sourceMap: true, // generate source maps
        noResolve: false // enforce type resolution
      },
      transformPath: function(path) {
        return path.replace(/\.ts$/, '.js');
      }
    },
    reporters: ['progress'],
    port: 9876,
    colors: true,
    logLevel: config.LOG_INFO,
    autoWatch: true,
    browsers: ['Chrome'],
    singleRun: false,
    concurrency: Infinity
  })
}

object under test: calculator.service.ts

export class Calculator {
  add(a: number, b: number): number  {
    return a + b;
  }
}

test itself: calculator.spec.ts

import { Calculator } from './calculator.service';

describe("A calculator", function() {
  it("adds integers correctly", function() {
    let things = new Calculator();
    expect(things.add(1, 2)).toBe(3);
  });
});

Upvotes: 2

Views: 1458

Answers (1)

Sune Monrad
Sune Monrad

Reputation: 26

The problem seems to be, that you are using ECMAScript 5, which makes the transpiler use requirejs. To fix this target es6 and set the module to es6 or add the npm packages "requirejs" and "karma-requirejs".

Upvotes: 1

Related Questions