What are the steps to effectively utilize a jest mock within a typed test fake when working with typescript?

I am facing an issue where I have defined an interface that requires certain functions to be implemented by objects. For instance:

interface MyInterface {
    someFunc: () => void,
    /* ... other details */
}

Now, I need to create a test to ensure that these functions are called under specific conditions.

To achieve this, I utilized test fakes in the following manner:

const obj: MyInterface = {
    ...fakeObj,
    someFunc: jest.fn(() => {})
};

/* ... actual testing code */

expect(obj.someFunc.mock.calls.length).toBe(1);

Initially, everything was working fine until I explicitly assigned a type to the obj variable. This change resulted in the error message:

Error: Property 'mock' does not exist on type '() => void'.

My intention behind adding types to my objects was to enable smooth usage of refactoring tools without the hassle of manually correcting all tests.

How can I effectively write a test to verify function calls while implementing explicit types?

Answer №1

If you want an effortless way to handle mocking in your tests, the mocked test helper is the solution for you.

By using the mocked test helper, you can leverage typings on your mocked modules and their deep methods, all based on the types defined in its source. This tool takes advantage of the latest TypeScript features, offering argument type completion directly in your IDE (instead of jest.MockInstance).

For example:

index.ts:

export interface MyInterface {
  someFunc: () => void;
}

export function main(obj: MyInterface) {
  return obj.someFunc();
}

index.test.ts:

import { main, MyInterface } from './';
import { mocked } from 'ts-jest/utils';

describe('63478184', () => {
  it('should pass', () => {
    const obj: MyInterface = {
      someFunc: jest.fn().mockReturnValueOnce('mocked value'),
    };
    main(obj);
    expect(mocked(obj.someFunc).mock.calls.length).toBe(1);
  });
});

Upon running the unit tests and generating coverage reports:

 PASS  src/stackoverflow/63478184/index.test.ts (12.902s)
  63478184
    ✓ should pass (8ms)

----------|----------|----------|----------|----------|-------------------|
File      |  % Stmts | % Branch |  % Funcs |  % Lines | Uncovered Line #s |
----------|----------|----------|----------|----------|-------------------|
All files |      100 |      100 |      100 |      100 |                   |
 index.ts |      100 |      100 |      100 |      100 |                   |
----------|----------|----------|----------|----------|-------------------|
Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        14.759s

Find the complete source code at: https://github.com/mrdulin/jest-codelab/tree/master/src/stackoverflow/63478184

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

Managing asynchronous variable assignment in Angular: tips and tricks

Within my Angular 6 application, there is a service where I declare a variable named "permittedPefs". This variable is asynchronously set within an httpClient.get call. @Injectable() export class myService implements OnInit { permittedPefs = [] ...

Utilizing React Typescript Discriminating Unions to choose between two different types based solely on props

In my project, I have a component that consists of different types: type Base = { color: string } type Button = { to: string } & Base type Link = { link: string linkNewTab: boolean } & Base type ComponentProps = Button | Link e ...

Testing the download functionality of a JavaScript unit

I need assistance in writing a unit test for the following function. Currently, I am only tracking how many times appendChild/removeChild is being called, but I believe there might be a better way to test this. Additionally, as a beginner in testing, I a ...

Exploring TypeScript interfaces with optional properties and returning types

As a newcomer to TypeScript, I am currently exploring the documentation and came across an example in the "Optional Properties" section that caught my attention: interface SquareConfig { color?: string; width?: number; } function createSquare(config: ...

When receiving JSON and attempting to store the data in a variable, I encounter an issue where it returns the error message "undefined is not iterable (cannot read property Symbol

I'm currently integrating the Advice Slip API into my project. I am experiencing an issue when trying to store the JSON data in a variable like so: let advice; fetch("https://api.adviceslip.com/advice").then(response => response.json()). ...

VSC is throwing a type error, but is it still possible to compile the code?

It seems like after downloading some extensions, I started encountering this issue which was not present before. My files are now displaying errors even though everything should be fine. https://i.sstatic.net/cr7Ef.png The error seems to be related to ca ...

Tips on utilizing storage.set() within google.maps.events.addListener(marker, 'dragend', function() { }); in Ionic 3

google.maps.event.addListener(Marker, 'click', (function(Marker) { return function() { this.storage.set('mylocation', this.Marker.getPosition()); } })(Marker)); polyfills.js:3 Uncaught TypeError: Cannot read property 'set ...

When the page hosted on Vercel is reloaded, `getStaticProps` does not function as expected

I'm currently working on a nextjs project and running into an issue where one of the pages returns a 404 error when it's reloaded. Within the page directory, I am using getStaticProps. pages - blogs.tsx - blog/[slug].tsx - index.tsx ...

Arrange Angular code in WebStorm by placing decorated variables after non-decorated ones

I am currently working on configuring arrangement rules for organizing class local variables before input variables. I want to structure them like this: private x; public y; @Input private z; @Input public q; However, despite my efforts, I have been unab ...

React-select or react-testing-library: Target change causing onChange not to fire in Jest mock

Struggling with mocking the react-select component, I've encountered an issue where the fireEvent.change from react-testing-library only triggers on the first call. I'm curious to understand why the change event is firing once and looking for a ...

Issue with logging messages using console.log in Knex migration script

My concern: I am facing an issue where the console.log('tableNobject: ', tableNobject) does not get logged in my knex migration script. I have attempted the following code snippets: //solution A export async function up(knex: Knex) { const ta ...

Custom claims fetched from Admin SDK are returning empty values

I am currently utilizing Firebase cloud functions in conjunction with Android to create a user with custom claims. However, I have encountered an issue where the custom claims are showing up as null despite following the documentation. Thank you in advanc ...

I attempt to transfer information from one of my components to another component

Why am I unable to display the data from the main component in the payment component? Solution export class BookListService { url: string = 'http://henri-potier.xebia.fr/books'; item:any=[]; public book: Book[]; constructor(private h ...

Error in TypeScript when compiling Mongoose document middleware

Problem After upgrading to TypeScript 3.4, I found that some of my Mongoose middleware functions were failing type checking. Error Message from TypeScript: model.ts:19:8 - error TS7017: Element implicitly has an 'any' type because type 'ty ...

Having trouble with an unexpected value in your Angular2 Service? Don't forget to add

I encountered an error in my Angular2 app: Error: (SystemJS) Unexpected value 'ReleasesService' declared by the module 'AppModule'. Please add a @Pipe/@Directive/@Component annotation. Here is my AppModule code: import { NgModule } fr ...

Having difficulty retrieving an angular file from a location outside of the asset folder

I'm encountering issues with a small project that is meant to read a log and present it in table format. Here is the outline of the project structure: project structure Within the LOG directory, I should be able to access motore.log from my DataServi ...

AWS CDK Pipeline not initiating on commit to Bitbucket

After configuring the connection in the pipeline settings, I applied the ARN as shown below: const pipeline = new CodePipeline(this,'SettingsPipeline' , { pipelineName: 'SettingsPipeline', synth: new CodeBuildSte ...

Provide initial values to a custom TypeScript hook

As a new TypeScript user, I am trying to implement a hook called useForm to use in all forms. However, I am facing an issue with passing initial values using the code snippet below. Can someone help me troubleshoot this? interface IForm1 { name?: strin ...

ESLint refuses to be turned off for a particular file

I am in the process of creating a Notes.ts file specifically for TypeScript notes. I require syntax highlighting but do not want to use eslint. How can I prevent eslint from running on my notes file? Directory Structure root/.eslintignore root/NestJS.ts r ...

Having trouble locating the type definition file for 'cucumber' when using the Protractor framework with Cucumber and Typescript

Currently immersed in working on Protractor with Cucumber and TypeScript, encountering a persistent issue. How can the following error be resolved: Cannot locate the type definition file for 'cucumber'. The file exists within the pr ...