Tips for writing unit tests for an object with a type union in TypeScript, Karma, and Sinon

Currently, I am conducting unit-testing for a project that utilizes TypeScript with the Angular framework. I am using Karma with Mocha and Chai frameworks for this purpose. The project includes an interface for the object, defined as follows:

interface ISolution {
    _id: string;
    paymentFrequency: PaymentFrequency;
};

Furthermore, the PaymentFrequency type is specified as:

type PaymentFrequency = 'MONTHLY' | 'ANNUAL' | 'SINGLE';

Within the controller,

open(solution: ISolution) { };

The issue arose when attempting to mock the solution as follows:

let solution = { _id: 'aa0', paymentFrequency: 'MONTHLY', ....};
let spy = sandbox.stub(controller, 'open').withArgs(solution);

Upon execution, TypeScript flagged an error stating "type string is not assignable to type paymentFrequency". If you have any suggestions on how to address this, please let me know.

Answer №1

To improve type checking, consider using interfaces for each type instead of using 'any'.

Click here for more information

Example:

interface ISolution {
    _id: string;
    paymentFrequency: monthly | annual | single
};

interface monthly{
    kind:"MONTHLY"
}
interface annual{
    kind:"ANNUAL"
}
interface single{
    kind:"SINGLE"
}


var fun=(obj:ISolution)=>{
 console.log("hererer",obj)
} 
var y:monthly={kind : "MONTHLY"}
var x= { _id: 'aa0', paymentFrequency:y}
fun(x)

Answer №2

When necessary, type checks in tests can be disabled by using <any> type casting, but this is not recommended. The typing system will recognize errors, such as the inconsistency between Monthly and MONTHLY, as well as the lack of compatibility with PaymentFrequency.

let solution = { _id: 'aa0', paymentFrequency: 'MONTHLY', ....};

This will result in the inferred type of solution being

{ _id: string, paymentFrequency: string }
. The important information that paymentFrequency should actually be MONTHLY is lost, causing compatibility issues with PaymentFrequency and making solution incompatible with ISolution.

The correct approach is:

let solution: ISolution = { _id: 'aa0', paymentFrequency: 'MONTHLY', ....};

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

Encountering issues with package resolution in VS Code while setting up a monorepo with yarn workspaces, Vite, React, and

I recently set up a monorepo using yarn@3 workspaces. Here is the structure of my root package.json: { "name": "hello-yarn-workspaces", "packageManager": "<a href="/cdn-cgi/l/email-protection" class="__cf_email__" ...

Arrange an array within an Angular component

I'm in the process of organizing my list-component made with Angular Material. <div style="width:30%;"> <mat-nav-list matSort (matSortChange)="sortData($event)"> <th mat-sort-header="stuff.name">Name</th> ...

Integrating VueJS seamlessly with your current Angular project

I am currently working on an angular application and I am interested in transitioning parts of it to a vueJS application. During development, all scripts are loaded in the main html file (in production mode they are bundled into app.js, but I would like t ...

Combining multiple Observables and storing them in an array using TypeScript

I am working with two observables in my TypeScript code: The first observable is called ob_oj, and the second one is named ob_oj2. To combine these two observables, I use the following code: Observable.concat(ob_oj, ob_oj2).subscribe(res => { this.de ...

Issue encountered when trying to use Array.sort() method to sort an array of objects

I'm facing an issue sorting an array of objects by a name property present on each object. When utilizing the sort() method with the given code snippet, I encounter the following error: ERROR ReferenceError: b is not defined This is my code block: m ...

Managing nested Angular repeats with counter

In the previous section of my document, I have a presentation layer that effectively organizes information within a shopping cart. This arrangement functions perfectly fine. At the lower portion, I employ the following code to generate form variables whic ...

I am facing an issue with updating the mat-table after pushing values to a

I have a uniqueFormGroup with UniqueFormArray and a special-table that displays the array. When I add new uniqueFormGroup to UniqueFormArray, the special-table doesn't add new row. I was attempting to implement trackBy, but I am unsure of where (and ...

Accessing geographical coordinates using Google Maps API with JavaScript

Hey there, I could really use your assistance. I'm looking to integrate a localization map on my website to track user locations. Any idea how I can go about doing this? Thanks in advance! ...

Angular seems to be resistant to adding my element onto the webpage

I have the initial setup of my Angular application here. My aim is to create a custom directive for the top menu that will be injected as an element. This particular element is named "product tabs" and you can find it at the center of the code block below. ...

What's the process for creating a synchronous function in AngularJS?

Is there a way to make storyboard.getAdressTimeLine run synchronously? I need storyboard.drawTimeLine to continue executing only after storyboard.getAdressTimeLine is done for (var i = 0; i < response.data.length; i++) { var obj=response.data[i]; var d ...

When using MERN Stack (with Typescript) on DigitalOcean, encountering an issue where HTML files are displayed instead of JS and

Upon checking the console, I encountered this https://i.sstatic.net/PWoT5.jpg The app has been developed using Ubuntu and Nginx so far with no firewall configuration yet in place. This is my first time deploying a MERN stack and utilizing DigitalOcean. ...

Adding TypeScript to your Vue 3 and Vite project: A step-by-step guide

After setting up my project by installing Vue and Vite using the create-vite-app module, I decided to update all the packages generated by 'init vite-app' to the latest RC versions for both Vue and Vite. Now, I am interested in using TypeScript ...

Can I create a unique Generic for every Mapped Type in Typescript?

I've got a function that accepts multiple reducers and applies them all to a data structure. For instance, it can normalize the data of two individuals person1 and person2 using this function: normalizeData([person1, person2], { byId: { init ...

The TypeScriptLab.ts file is generating an error message at line 23, character 28, where it is expecting a comma

I am attempting to convert a ts file to a js file. My goal is to enter some numbers into a textarea, and then calculate the average of those numbers. However, I encountered an error: TypeScriptLab.ts(23,28): error TS1005: ',' expected. I have in ...

Error: Attempting to modify the ip property of an #<IncomingMessage> object that is read-only

Currently, I am in the process of developing a middleware that is intended to assign the user's IP address based on the cloudflare header provided. This method has worked successfully on previous projects of mine, but now it seems to be encountering i ...

Modifying the value upon saving in Adonis JS model

Using Adonis js I am facing an issue when trying to convert an ISO string to Datetime while saving data (the opposite of serializing DateTime fields to ISO string). I cannot find a way to do this in the model, like I would with a mutator in Laravel. Whene ...

Is it possible to continuously re-render a React Functional Component with Axios and useState/useEffect?

Seeking assistance with creating a React Functional Component using Typescript to fetch data from an API and pass it to another component. However, encountering the error message "Error: Too many re-renders. React limits the number of renders to prevent an ...

When I try to use angular.injector.invoke, I am encountering an issue

As I was diving into learning angular, I came across a fascinating blog post that explained how we can access factories/services outside of controllers using angular.injector(). Excited to try it out, I attempted to implement this approach only to be greet ...

Merge two JSON data sets in AngularJS to iterate through the 'Products' and 'SelectedProducts' arrays

Currently, I have a table displaying all available products from a JSON array. Additionally, there is another JSON array that contains the products selected by the user previously. Upon returning to the list of products, my goal is to update the display to ...

Linking Angular with property of an object

Is there a way to ensure that the binding of object properties works properly? For instance, in my controller I have: $scope.reviews = { rating_summary: 4, items: [ { title: 'A Title'}, etc... ] } And in my view: <li ng-repeat="review i ...