Basic Karma setup with Typescript - Error: x is undefined

I am trying to configure a basic test runner using Karma in order to test a TypeScript class.

However, when I attempt to run the tests with karma start, I encounter an error stating that

ReferenceError: Calculator is not defined.
It seems like either the karma runner is not importing the transpiled source file or the preprocessor is failing to transpile the source code.

You can find my source code in this repository here, and the relevant parts are provided below. Can you help me figure out how to configure my setup properly?

Based on my current understanding, both the transpiler and the 'files' configuration property in karma should be loading the calculator class for me.

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

/test/calculator.test.js

describe('Demo Test Runner', function() {
  var calc = new Calculator();
  it('should return 3 for 1 + 2', function() {
   expect( calc.add(1,2) ).toBe(3);
  });
});

package.json

...
"devDependencies": {
  "jasmine-core": "^2.5.2",
  "karma": "^1.3.0",
  "karma-chrome-launcher": "^2.0.0",
  "karma-jasmine": "^1.0.2",
  "karma-typescript-preprocessor": "^0.3.0"
}

karma.conf.js

module.exports = function(config) {
 config.set({

 ...
 frameworks: ['jasmine'],

 files: [
    'lib/**/*.js',
    'test/**/*.js'
  ],

 preprocessors: {
   '**/*.ts': ['typescript']         
 },

 typescriptPreprocessor: {
    // options passed to the typescript compiler 
    options: {
      sourceMap: true,
      target: 'ES5',
      module: 'amd',
      noImplicitAny: true,
      noResolve: true,
      removeComments: true,
      concatenateOutput: false
    },
    // transforming the filenames 
    transformPath: function(path) {
      return path.replace(/\.ts$/, '.js');
    }
 }
 ...

Answer №1

When you define your calculator as

export class Calculator{...}

This indicates that your /lib/calculator.ts is a module and its classes must be imported by other modules in order to be visible (they are not global).

Therefore, your /test/calculator.test.js needs to somehow import this module. The method for doing so will depend on the module configuration in your tsconfig.json

In your situation, you may want to use either "module" : "commonjs" or "module": "amd".

However, you will require an additional plugin for karma to load these modules. If using amd, something like karma-requirejs would be necessary; for commonjs, you might need something like karma-webpack. Then, you would need to utilize the appropriate syntax to import it in your js file (e.g.

var MyCalculator = require('/lib/calculator');
)

Your other option is to not "export" your Calculator class, making it globally accessible. However, it is advisable to try and make the module approach work as that is recommended for larger applications.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Manipulating and inserting objects into an array using React and Typescript with an undefined type

As I embark on my TypeScript journey in React, I decided to test my knowledge by creating a simple Todo App. Everything seems to be working fine except for one issue! After adding a new task and hovering over it, I received the following error message (tr ...

What is the correct way to utilize window.scrollY effectively in my code?

Is it possible to have a fixed header that only appears when the user scrolls up, instead of being fixed at the top by default? I've tried using the "fixed" property but it ends up blocking the white stick at the top. Adjusting the z-index doesn&apos ...

When using the react-query library, the useQuery hook may not always return a defined value, leading

Experimenting with reactQuery in a demo app showcased in this repository. The app interacts with a mock API found here. Encountering an issue using the useQuery hook to call the following function in the product API file: export const getAllProducts = asy ...

Obtain the Enum's Name in TypeScript as a String

I am currently looking for a solution to transform the name of an enum into a string format. Suppose I have the following Response enum, how can I obtain or convert 'Response' into a string? One of my functions accepts any enum as input and requi ...

Using Angular 4 to monitor changes in two-way binding properties

Recently, I developed a unique toggle-sorting component that examines if the current sorting parameters align with its sorting slug and manages clicks to reflect any changes. // toggle-sorting.component.ts @Input() sortingSlug: string; @Input() currSorti ...

Using NestJS to import and inject a TypeORM repository for database operations

This is really puzzling me! I'm working on a nestjs project that uses typeorm, and the structure looks like this: + src + dal + entities login.entity.ts password.entity.ts + repositories ...

Differentiating Service Class and Typescript Class in Angular 6

I am looking for a detailed explanation of service classes in Angular. From my perspective, both service classes and typescript classes serve the same purpose. So, what sets them apart from each other? ...

The type '[Images]' cannot be assigned to type 'string'

I am attempting to pass an array of objects through props, but encountered the following error: (property) images: [Images] Type '[Images]' is not assignable to type 'string'.ts(2322) ProductBlock.tsx(4, 5): The expected type co ...

Combining class and data within an iteration while utilizing ngFor

I have a dynamic table with rows generated using ngFor <tbody> <tr *ngFor="let item of Details"> <div class="row details-row row-cols-lg-2 row-cols-1" *ngIf="closureDetails"> <div ...

Having difficulty deciphering the legend in the Highcharts library for Angular (angular-highcharts)

I have a requirement to display two datasets as dual column charts. (2) [{…}, {…}] 0: historyDate: "2021-02-10T10:00:000Z" documentStatusHistory: CANCELLED: 6 COMPLETED: 52 IN_PROGRESS: 1 OPEN: 1 ...

JavaScript - Modifying several object properties within an array of objects

I am attempting to update the values of multiple objects within an array of objects. // Using a for..of loop with variable i to access the second array and retrieve values const AntraegeListe = new Array(); for (let i = 0; i < MESRForm.MitarbeiterL ...

The program experienced an issue with TypeError: Attempting to access properties of an undefined variable ('_id')

I am attempting to show a data entry (with a unique id) in Angular, but I'm encountering the following error: ERROR TypeError: Cannot read properties of undefined (reading '_id') The service for retrieving the specific id is defined as: g ...

When ts-loader is used to import .json files, the declaration files are outputted into a separate

I've encountered a peculiar issue with my ts-loader. When I import a *.json file from node_modules, the declaration files are being generated in a subfolder within dist/ instead of directly in the dist/ folder as expected. Here is the structure of my ...

Simulate a complete class with its constructor, instance methods, and static functions

I have been searching for a comprehensive example that demonstrates how to properly mock all three elements (ClassA constructor, ClassA.func1 instance function, and ClassA.func2 static function) in my TypeScript project. In the code under test, I need to v ...

Angular Universal involves making two HTTP calls

When using Angular Universal, I noticed that Http calls are being made twice on the initial load. I attempted to use transferState and implemented a caching mechanism in my project, but unfortunately, it did not resolve the issue. if (isPlatf ...

Leverage context to facilitate communication between components operating at various levels of the system

I am currently working on the settings pages of my applications. Each page features a common SettingsLayout (parent component) that is displayed across all settings pages. One unique aspect of this layout is the presence of an ActionsBar, where the submit/ ...

Is there a workaround in TypeScript to add extra details to a route?

Typically, I include some settings in my route. For instance: .when('Products', { templateUrl: 'App/Products.html', settings: { showbuy: true, showex ...

Can someone assist me with running queries on the MongoDB collection using Node.js?

In my mongodb collection called "jobs," I have a document format that needs to display all documents matching my query. { "_id": { "$oid": "60a79952e8728be1609f3651" }, "title": "Full Stack Java Develo ...

Filling a data entry with simultaneous commitments

Sample code: type Alphabet = 'a' | 'b' | 'c'; const alphabetMap: Record<Alphabet, null> = { 'a': null, 'b': null, 'c': null} // Select any asynchronous processing function you prefer funct ...

Embedding Globalize.js into an Angular component

Hey there! I'm currently working on building an Angular 4 application that needs to support L10n. I've decided to incorporate globalize into my project. Below is a snippet of my App component: import { Component, OnInit } from '@angular/c ...