2

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);
  });
});
Community
  • 1
  • 1
Jammer
  • 441
  • 5
  • 15
  • 1
    would you mind sharing your files on plunkr to understand your project structure? – Sreekanth Oct 23 '16 at 20:25
  • 1
    The tutorial you have referenced does not appear to use modules, but you are - your code has imports and exports. As such, I cannot see how this could be answered without using an additional karma plugin. – cartant Oct 23 '16 at 20:43
  • @sreekanth I wasn't sure how to get this running on Plunker, because I'm not sure how npm interacts with it. I'm so sorry. I created a github repo that demonstrates the problem if that helps: https://github.com/jammerware/karma-question. Just clone, npm install, and npm test. – Jammer Oct 25 '16 at 17:31
  • @cartant You make a good point. This could be the misunderstanding that's causing my problem. I saw in the tutorial that the author is making use of /// statements to expose the object under test, but I'm not sure I really understand how that works. Sorry for the confusion - I'm new to JS testing. See the github repo I linked in a previous comment. If you were solving this problem, would you make use of a plugin? Would you use karma-browserify? Thanks for your help and time. – Jammer Oct 25 '16 at 17:33

1 Answers1

1

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".