Using Jasmine to Jest: Mocking Nested function calls

I am currently working on testing my TypeScript functions with Jasmine:

//AB.ts

export async function A() {
}
export async function B() {
    A();
}

My goal is to unit test function B by mocking out function A to see if it is called. Here is the code I have so far:

//AB.spec.ts
import * as AB from './AB'

describe('AB has a function B that ', () => {
    it('calls A', async () => {
        let ASpy: jasmine.Spy;
        ASpy = spyOn(AB, 'A').and.returnValue(Promise.resolve({}));
        await AB.B();
        expect(ASpy).toHaveBeenCalled();
    });
});

Upon running the test, I received an error indicating that ASpy was never called. However, after investigating further, I confirmed that the A function was indeed called. It seems like the mock I created for the function did not trigger as expected. I tried relocating the A function to a separate file and mocked it there for the test in AB.spec.ts; surprisingly, the test passed as the expectation showed that ASpy was called. I'm puzzled as to why having both functions in the same file caused the test to fail while separating them into different files made it pass. I would appreciate any insights or help on this matter! Although moving the functions to separate files solved the issue for now, I prefer not to rely on this approach in future projects.

Answer №1

It appears that in your code, you are utilizing

Aspy = spyOn(AB,'A'); 

However, AB is not an instance of a component or class; rather, it is simply a constant used to import these global functions into your spec file.

The issue at hand does not stem from any errors in your testing of "async" functions specifically. Instead, the problem lies in how you are creating spies for your functions without objects related to classes or components. To address this, consider revisiting your approach and exploring alternative solutions outlined in the thread linked below to see if adjusting your spies using one of the provided methods allows your initial tests to execute smoothly.

Using Jasmine to spy on a function without an object

Answer №2

I discovered a solution to effectively mock A within B. All I had to do was include the exports keyword in my function call:

export async function B() {
    exports.A();
}

By doing this, it enables B to access the definition of A and allows the .spec file to recognize that A is referencing the exported method of A.

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 correct method for typing a React functional component with properties?

Here's a react functional component I have created... const MyFunction = () => { // lots of logic MyFunction.loaded = someBoolean; return <div>just one line</div> } MyFunction.refresh = () => ....... I added two properti ...

Typescript struggles to identify properties that have no business being there

In my function for formatting data, the "values" contained within this data are clearly defined. However, TypeScript is failing to recognize new properties that are invalid when mapping these values. The issue can be best understood by looking at the code ...

Playing around with TypeScript + lambda expressions + lambda tiers (AWS)

Having trouble importing modules for jest tests in a setup involving lambdas, lambda layers, and tests. Here is the file structure: backend/ ├─ jest.config.js ├─ package.json ├─ babel.config.js ├─ layers/ │ ├─ tsconfig.json │ ├ ...

Guide to simulating a function using .then within a hook

I am using a function that is called from a hook within my component. Here is my component: ... const handleCompleteContent = (contentId: string) => { postCompleteContent(contentId, playerId).then(data => { if (data === 201) { ... The caller ...

The method of implementing an index signature within TypeScript

I'm currently tackling the challenge of using reduce in Typescript to calculate the total count of incoming messages. My struggle lies in understanding how to incorporate an index signature into my code. The error message that keeps popping up states: ...

Updating and saving data in Ag-Grid with server communication

Is it possible to create a grid using Ag-Grid on Angular that fetches data from a local JSON file? And how can the edited row data be saved and sent to the server or back to the local JSON file? In summary, I would like to know how to save edited row data ...

A TypeScript class utilizing a static variable with the singleton design pattern

I have a query regarding the most effective way to code this scenario: Within a class, I require a static variable that is accessible throughout the entire project: connection Singleton without namespace: class Broker { static connection: Connection = u ...

The Component TSX is reporting a Type error stating that the Property 'onChange' is not present in the type '{ key: string; value: Model; }' as required by Props

While running the following command: npm run build I encountered an error that needs resolution: /components/Lane.tsx:37:18 Type error: Property 'onChange' is missing in type '{ key: string; value: StepModel; }' but required in type &a ...

Is it possible to create a combined header/declaration file in Golang within a single file?

My goal is to automatically generate Golang declaration files based on .json data. While with TypeScript I can consolidate types/declarations in one file using namespaces, it seems more complex to achieve the same with Golang packages and namespacing. In ...

What is the best way to grasp the connections between the any, unknown, {} data types and their relationships with other types?

Seeking to comprehend relationships between different types, the following code is presented: type CheckIfExtends<A, B> = A extends B ? true : false; type T1 = CheckIfExtends<number, unknown>; //true type T2 = CheckIfExtends<number, {}> ...

What does it signify when it is stated that "it is not a descendant of the indexer"?

Currently, I am diving into Typescript with the help of this informative guide on indexer types. There is a specific piece of code that has me puzzled: interface NumberDictionary { [index: string]: number; length: number; // okay, length shoul ...

Redux ConnectedProps will always have a type of never

I am facing an issue while attempting to connect a component to my Redux store following the steps outlined in the official documentation guide. The props that are connected seem to be coming through as type never. Here is a snippet of my code: Type defi ...

Guide on linking action observables to emit values in sync before emitting a final value

If you're familiar with Redux-Observable, I have a method that accepts an observable as input and returns another observable with the following type signature: function (action$: Observable<Action>): Observable<Action>; When this method r ...

Tips for organizing an array of objects that contain null properties

Here is an array that I need help with: "data": { "risks": [ { "id": "22", "name": true, "surname": 0.5, "age": 0.75, "heigth" ...

Trouble occurs in the HTML code when trying to access a property from an inherited interface in Angular

Currently, I am working with Angular 17 and have encountered a specific query: In my project, there is an IDetails interface containing certain properties: export interface IDetails { summary: Summary; description: string; } Additionally, there is an ...

Triggering two function calls upon submission and then waiting for the useEffect hook to execute

Currently, I am facing a challenge with form validation that needs to be triggered on submit. The issue arises as some of the validation logic is located in a separate child component and is triggered through a useEffect dependency from the parent componen ...

What are the reasons for deprecating bindToController in Typescript?

When I am creating an AngularJS directive using TypeScript, I typically use the bindToController property to bind parameters to the controller for easy access. export class MyDirective implements IDirective { controller = MyController; controllerA ...

Merging two arrays in Typescript and incrementing the quantity if they share the same identifier

I am currently working on my Angular 8 project and I am facing a challenge with merging two arrays into one while also increasing the quantity if they share the same value in the object. Despite several attempts, I have not been able to achieve the desired ...

There was an error in calling `prisma.user.findUnique()`:

Here is my code snippet for the API route: export const POST = async (req: NextRequest) => { ... try { const { email, name, password } = await req.json(); console.info(email, name, password); const existingUser = await prismadb.user.findUn ...

Is the array index a string or a number?

Why is it that when looping over the indexes of an array they appear as strings, even though using a string to index an array is not allowed? Isn't this inconsistency puzzling? for (const i in ["a", "b", "c"]) { console.log(typeof i + " " + i + " " ...