Using Typescript and Sinon to pass unit test parameters into a constructor

I need to verify that a constructor within a function I am currently testing is called with the right parameters. Here's an example of what I'm trying to achieve:

Let's say we have a class called Foo:

export class Foo {

    constructor(param: string) {
    }
}

Then, we have a function named bar() that creates an instance of Foo:

import { Foo } from './foo';

export function bar() {
    const foo = new Foo('test');

    // perform some actions using foo
}

Lastly, we have a unit test for the function bar():

import { expect } from 'chai';
import sinon from 'ts-sinon';
import { bar } from '../src/bar';

describe('bar', () => {

    beforeEach(() => {
    });

    it('should call foo with the correct parameters', async () => {
        bar();
        // TODO: Similar to this line:
        // expect(fooStub).calledOnceWithExactly('test');
    });
});

Answer №1

It is not possible to test if the constructor is called with the correct parameter (Reference).

However, you can verify if the constructor's parameter is correctly set to a property.

Here are some notes:

  1. You should follow the rule no-useless-constructor.
  2. From a design pattern perspective, in my humble opinion, it's better to define the function bar inside Foo as Foo's method if bar only depends on Foo.

If you are practicing TDD, here is how I usually approach it: test foo and bar separately to ensure that both Foo and bar are correct.

// File: Foo.ts
export default class Foo {
  someAwesomeProperty: string;

  constructor(param: string) {
    this.someAwesomeProperty = param;
  }
}

Unit test for Foo.

// File: test1.spec.ts
import { expect } from 'chai';
import Foo from './Foo';

describe('Foo', function () {
  it('should initiate someAwesomeProperty', function () {
    const foo = new Foo('test');
    expect(foo).to.have.property('someAwesomeProperty', 'test');
  });
});

Next, move on to bar. If you are following the TDD approach, at your current phase, you may need to return the foo object to check. This action could be temporary just to ensure the tests pass. For example:

// File: bar.ts
import Foo from './Foo';

export default function bar() {
  const foo = new Foo('test');
  return foo;
}

Then unit test bar.

// File test2.spec.ts
import { expect } from 'chai';
import Foo from './Foo';
import bar from './bar';

describe('bar', function () {
  it('should call foo with correct parameters', function () {
    const test = bar();
    expect(test).to.be.instanceOf(Foo);
    expect(test).to.have.property('someAwesomeProperty', 'test');
  });
});

Finally, run the tests using ts-mocha, for example.

$ npx ts-mocha test/*.spec.ts --exit


  Foo
    ✓ should initiate someAwesomeProperty

  bar
    ✓ should call foo with correct parameters


  2 passing (9ms)

$

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

What is the best way to assign ngModel to dynamically inserted input rows in Angular 4+ (specifically in a mat-table)?

Just a quick question - how can I add ngModel to dynamically added new input rows? I have a Mat table with multiple rows and an "add element" method that adds a new row every time a button is clicked. This way, I want to bind the user-entered values and se ...

Is it possible for TypeScript to preserve the return type while consolidating multiple classes or objects of functions in a reducer method?

Describing my issue with the title was challenging, but here it is: I have several objects that follow this structure: type TUtilityFunction = {[key: string]: <T>(a: T, b: any) => T} For example: class UtilityA{ DoSomeWork = function (arg1: So ...

Discover the geolocation data for post code 0821 exclusively in Australia using Google Maps Geocoding

I'm having trouble geocoding the Australian postcode 0821. It doesn't seem to reliably identify this postcode as being located within the Northern Territory, unlike 0820 and 0822 which work fine. Here's an example of what I'm doing: ...

When I try to install dependencies with Hardhat, the "Typechain" folder does not appear in the directory

After installing all the dependencies, I noticed that the "typechain" folder was missing in the typescript hardhat. How can I retrieve it? Try running npm init Then, do npm install --save-dev hardhat Next, run npx hardaht You should see an option to se ...

Exploring Angular's ngFor feature in building a dynamic accordion menu that automatically closes one panel and opens another when clicked

The Angular Material accordion component is a key feature in my Angular project. Utilizing an ngFor loop to iterate through the information stored in menuItems, I dynamically create a new expansion panel for each item. With two components in play, I seaml ...

Issue TS7053 occurs when trying to access any index of the target of a React.FormEvent<HTMLFormElement>

I've been working on adapting this tutorial to React and TypeScript. Here is the code snippet I have implemented for handling the onSubmit event: const handleSignUp = (event: React.FormEvent<HTMLFormElement>) => { event.preventDefault(); ...

I am unable to utilize the outcome of a custom hook within a function or within an effect hook

I've developed a unique custom hook that retrieves a list of individuals File: persons.hooks.ts import {useEffect, useState} from "react"; import Person from "../../models/person/Person"; const usePersons = () => { const ...

Using Typescript generics to enhance arrays

I am looking to extend a generic list of Array that has been previously extended from my class. How can I accomplish this in the correct way? export interface DeliveryMethod { readonly id: string; readonly company: string; readonly cost: number; re ...

Convert JavaScript to TypeScript by combining prototype-based objects with class-based objects

My current challenge involves integrating JavaScript prototype with class-based programming. Here is an example of what I've tried: function Cat(name) { this.name = name; } Cat.prototype.purr = function(){ console.log(`${this.name} purr`) ...

An unknown error has arisen: "The page https://registry.yarnpkg.com/react-native-template-react-native-template-typescript cannot be located."

Once I uninstalled the react-native-cli, I attempted to start a React Native project with a typescript template using the following command: npx react-native init MyApp --template react-native-template-typescript However, I encountered an error message: ...

Utilize tree-shaking functionality within your TypeScript project

In the process of developing a TypeScript telemetry library using OpenTelemetry, I am exploring ways to incorporate tree-shaking to allow consumers to selectively import only the necessary modules and minimize the overall bundle size. The project directory ...

What is the official name of the key type for the Built-in Object?

There was a built-in type that I used in the past which represented the union of all possible object keys. It was named objectKey or something similar. Here is an example: type objectKey = string | number | symbol Unfortunately, I am drawing a blank on t ...

The TS2583 error in TypeScript occurs when it cannot locate the name 'Set' within the code

Just started my Typescript journey today and encountered 11 errors when running tsc app.ts. Decided to tackle them one by one, starting with the first. I tried updating tsconfig.json but it seems like the issue lies within node_modules directory. Any help ...

The error message "TypeError: Unable to access property 'ready' of undefined in IONIC2" is displayed

I am currently working on integrating the InAppBrowser in IONIC2. Successfully installed Browser Plugin ionic plugin add cordova-plugin-inappbrowser Here is my .TS code for opening the browser browser(url:string) { this.platform.ready().then(() => ...

Breaking down an object using symbols as keys in Typescript

I'm encountering an error when running this code Type 'symbol' cannot be used to index type '{ [x: string]: string; }'.: let symbol = Symbol() let obj = { [symbol] : 'value'} let { [symbol]: alias } = obj // ...

Module type hint (namespace)

My dilemma lies in the process of importing a module and trying to typehint it within a function, yet I'm faced with this error message: Cannot use namespace 'joi' as type import joi from "joi"; export function init(cb: (joi: joi) => ...

Encountering the error "bash: typeorm: command not found" post installation of typeorm globally on a linux system

Operating System: Running macOS Sierra v 10.12.6 This is my first experience using Typescript and typeorm as I attempt to develop an application. I have tried both of the following commands to install typeorm: npm i -g typeorm & sudo npm i -g type ...

Webpack: The command 'webpack' does not exist as a recognized cmdlet, function, script file, or executable program

Attempting to set up a new project using webpack and typescript, I have created the project along with the webpack file. Following the instructions on the webpack website, I successfully installed webpack using npm install webpack webpack-cli --save-dev ...

Error encountered when implementing TypeScript with React's useState hook using generics

While utilizing a generic type in the react useState hook, I encounter an unusual error: // Extract from react typings type SetStateAction<S> = S | ((prevState: S) => S); type Dispatch<A> = (value: A) => void; declare function useState< ...

TypeScript is throwing an error about a missing property, even though it has been defined

Within the PianoMK1Props component, there is a prop known as recording which accepts an object with specific properties. The structure of this object is defined like so(the state variable): const [recording, setRecording] = useState({ mode: "REC ...