Tips for simulating or monitoring an external function without an object using Typescript 2 and Jasmine 2 within an Angular 4 application

In order to verify if a function called haveBeenCalledWith() includes the necessary parameters, I am seeking to validate the correctness of my call without actually executing the real methods.

I have experimented with multiple solutions sourced from various places such as this post on Stack Overflow and another one found on Jasmine JS group discussion.

You can find my attempts documented in a Plunker that might offer some insights here

Currently, I am utilizing an external library called date-fns.

The Angular 4 Pipe I created looks like this:

import { Pipe, PipeTransform } from '@angular/core';
// Importing all 'date-fns' works but causes issues with tree shaking, so it's not ideal
import * as format from 'date-fns/format'; 

@Pipe({
    name: 'dateFnsFormat'
})
export class DateFnsFormatPipe implements PipeTransform {

    transform(value: any, args?: any): any {
        return format(value, args);
    }

}

My objective is to test the invocation of the format function.

Below are my testing scenarios without mock implementations:

import * as format from 'date-fns/format';

const xmasDay = '2017-12-25 12:30:00';

// Succeeds with actual function
it('should transform the date from Y-m-d H:m:s to d/m/Y', () => {
    const dateFnsFormatPipe = new DateFnsFormatPipe();
    expect(dateFnsFormatPipe.transform(xmasDay, 'DD/MM/YYYY')).toBe('25/12/2017');
});


// Succeeds with actual function
it('should transform the date from Y-m-d H:m:s to d/m/Y H:m:s', () => {
    const dateFnsFormatPipe = new DateFnsFormatPipe();
    expect(dateFnsFormatPipe.transform(xmasDay, 'DD/MM/YYYY HH:mm:ss')).toBe('25/12/2017 12:30:00');
});

Here, I describe my various attempts along with the encountered errors:

// #1 Attempt using spyOn(window, 'function');
// Error: Error: format() method does not exist
it('#1 should transform the date from Y-m-d H:m:s to d/m/Y H:m:s', () => {
    spyOn(window, 'format');

    const dateFnsFormatPipe = new DateFnsFormatPipe();
    dateFnsFormatPipe.transform(xmasDay, 'DD/MM/YYYY HH:mm:ss');
    expect(window.format).toHaveBeenCalled();
});

// #1b Attempt using spyOn(global, 'function');
// Error: Error: format() method does not exist
it('#1b should transform the date from Y-m-d H:m:s to d/m/Y H:m:s', () => {
    spyOn(global, 'format');

    const dateFnsFormatPipe = new DateFnsFormatPipe();
    dateFnsFormatPipe.transform(xmasDay, 'DD/MM/YYYY HH:mm:ss');
    expect(global.format).toHaveBeenCalled();
});
...
... (More attempts included)
...

Note: Although I am demonstrating examples within the date-fns library, my intention is to implement the same concept with diverse libraries. Additionally, I aim to avoid importing the main file due to concerns regarding tree shaking when leveraging webpack.

Answer №1

When attempting something like this...

it('should', () => {
      const dffp = new DateFnsFormatPipe();
      spyOn(DateFnsFormatPipe, 'transform').and.callThrough();
      spyOn(dffp, 'format');

      dateFnsFormatPipe.transform(xmasDay, 'DD/MM/YYYY');

      expect(dffp.format).toHaveBeenCalledWith(xmasDay, 'DD/MM/YYYY');
    })

This approach has been effective for me. You may need to make adjustments to fit your specific needs, but it should be a good starting point.

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

Having trouble importing zone.js in Angular 14 and Jest 28

I am currently in the process of updating to Angular 14. Everything is going smoothly except for setting up jest. Since I have Angular 14 libraries included in my build, I need to utilize jest-ESM support. Below is my configuration: package.json { &qu ...

Angular 8 encountered a 404 (Not Found) error when trying to POST to http://localhost:4200/assets/data/students.json

I'm currently working on a project that involves fetching array data through HTTP and should also allow for the addition of new arrays using HTTP. However, every time I attempt to post a new array, I encounter the following error: POST http://local ...

`A bug in my Angular 4 application causes a TypeError when hosted on IIS`

After hosting an Angular 4 app on IIS, it seems there is an issue when accessing the app from machines other than the ones used for development. An error message " 'Uncaught TypeError: undefined is not a function' common.es5.js:3084" appears on t ...

Looking to build a unique form validator for two inputs? Ensure that one input number is consistently larger than the other with this guide

Is it possible to create a custom form validator with 2 inputs? My goal is to ensure that one input number is always greater than the other. ValidateMaxMin(control: FormControl) { console.log(control.value.productMin); if (control.value.productM ...

storing information in localStorage using react-big-calendar

Incorporating react-big-calendar into my project, I encountered a problem where the events in the calendar would disappear upon page refresh despite saving them in localStorage. I had planned to store the events using localStorage and retrieve them later, ...

Is there a convenient HTML parser that is compatible with Nativescript?

I have tested various libraries like Jquery, Parse5, and JsDom, but unfortunately they are not compatible with nativescript. Jquery relies on the DOM, while Parse5 and JsDom require Node.js which is currently not supported by nativescript. I am in need of ...

Ways to merge two distinct arrays [Angular and Typescript]

I am faced with a task where I need to merge two array lists in order to create a new array list that contains all the values associated with a common UUID in both lists. The final list should include all the values linked to the UUID in each of the origin ...

Determine the tuple data type by analyzing a union of tuples using a single element as reference

Looking for a way to work with a union of tuples: type TupleUnion = ["a", string] | ["b", number] | [Foo, Bar] // ... In need of defining a function that can handle any type K extends TupleUnion[0], with the return type being inferred ...

What exactly is the purpose of the colon in JavaScript's import statement?

Looking at the following example. import { QueryClientContract, TransactionClientContract } from '@ioc:Adonis/Lucid/Database' I am puzzled by the use of colons and I am unsure about where the imported files are being referenced from. ...

Create a new data structure in TypeScript that stores multiple values in a

For my TypeScript project, I came across a situation where I needed to utilize Promise.all(...) to handle an array of multiple items: Promise.all( firstRequest, secondRequest, ..., nthRequest ) .then((array : [FirstType, SecondType, ..., NthType]) ...

What is the best way to elucidate this concept within the realm of TypeScript?

While diving into my ts learning journey, I came across this interesting code snippet: export const Field:<T> (x:T) => T; I'm having trouble wrapping my head around it. It resembles the function definition below: type myFunction<T> = ...

Using WebSockets in Angular 4

Currently in the process of developing a chat application using Angular 4 and WebSocket. I found guidance from this Angular WebSocket tutorial This is the source code for the WebsocketService: import { Injectable } from '@angular/core'; import ...

Unassigned variable in need of initialization within Angular 2

There seems to be an issue with the two-way data binding not functioning correctly. I am trying to retrieve the data using {user | json}, but I encounter an error when using [(ngModel)] = "user.username". Data Model export interface UserModel { ...

Exclude weekends from DateTime

Currently working on a task list and aiming to set the default date to 3 days from now, excluding weekends. Utilizing Vue and thinking a computed property might be the solution? DateTime.utc().plus({ days: 3 }).toFormat('yyyy-MM-dd HH:mm:ss'), ...

Tips for using a loop variable as an argument in a method call for an attribute reference

Within the html code of my component, I have the following: <div *ngFor="let image of images; let i=index;" class="m-image-wrapper"> <i class="fa fa-times m-delete-img" (click)="removeImage(i, {{image.docname ...

What is the best way to first identify and listen for changes in a form

In Angular, there are reactive forms that allow you to track changes in both the complete form and specific fields: this.filterForm.valueChanges.subscribe(() => { }); this.filterForm.controls["name"].valueChanges.subscribe(selectedValue => { }); ...

Is it possible to utilize the System.import or import() function for any JavaScript file, or is it restricted to single module-specific files?

After reading an intriguing article about the concept of dynamic component loading: I am interested in learning more about the use of System.import. The author demonstrates a specific syntax for loading the JavaScript file of the module that needs to be d ...

Troubleshooting display glitches on Bootstrap modals in Internet Explorer 11 and Microsoft Edge

I have been encountering rendering artifacts consistently across various versions of IE11 and Edge, on different devices with varying graphics cards and drivers, as well as different update statuses of Windows 10. The screenshots indicate some of these ar ...

Can JSON Web Tokens be utilized in a browser environment?

Searching for a way to parse the JWT token led me to this jsonwebtoken library https://www.npmjs.com/package/jsonwebtoken. It appears to be tailored for NodeJS. Is it feasible to utilize this library in the browser? My attempts so far have resulted in the ...

Record the variable as star symbols in the VSTS Extension

I am working on a VSTS extension using Typescript and utilizing the vsts-task-lib Currently, I am encountering an issue with the execSync function, which displays the command being executed. However, I need to hide a token obtained from a service by displ ...