Managing file imports in Angular 2+ Unit Testing

Within my project, there are various utility functions that handle data transformations and other tasks. These functions are not contained within a class and are utilized across multiple utility files.

Being relatively new to angular testing, I've spent some time searching for a way to stub the imports of a tested file. To illustrate this issue, take a look at the following:

/utils/helpers.ts

export const sumNumber = (a: number, b: number): number => {
  return a + b;
}

/utils/file-i-want-to-test.ts

import { sumNumber } from "./helpers";

export const sumArrays = (arr1: number[], arr2: number[]): number[] => {
  const len = arr1.length > arr2.length ? arr1.length : arr2.length;
  const result = new Array(len).fill(0);

  return result.map((_, index) => sumNumber(arr1[index] || 0, arr2[index] || 0));
}

/utils/file-i-want-to-test.spec.ts

import { sumArrays } from './file-i-want-to-test';

describe('Utilities', () => {

  describe('Function - sumArrays', () => {

    it('should return empty array', () => {
      const actual = sumArrays([], []);
      expect(actual).toEqual([]);
    });

    it('should call sumValue 2 times', () => {
      const actual = sumArrays([1, 2], [3, 4]);

      // How to test that sumArray is actually calling his dependency sumNumber?
    });
  });
});

Challenge

For effective unit testing of the sumArrays function, it is necessary to stub its dependency sumNumber. How can this be achieved?

Answer №1

Give this a try:

import * as utilities from './helpers'; // import helpers in this manner

describe('Utilities', () => {

  describe('Function - sumArrays', () => {

    it('should yield an empty array', () => {
      const result = sumArrays([], []);
      expect(result).toEqual([]);
    });

    it('should invoke sumValue 2 times', () => {
      spyOn(utilities, 'sumNumber'); // this only acts as a placeholder and returns undefined
      const result = sumArrays([1, 2], [3, 4]);
      expect(utilities.sumNumber).toHaveBeenCalled(); // verify if it was called
      // How can we ensure that sumArray is truly calling its dependency sumNumber?
    });
  });
});

The spyOn function has additional functionality, such as making it return undefined.

spyOn(helpers, 'sumNumber').and.callFake(/* your fake function here */);
// create a custom function to be called whenever sumNumber is invoked

spyOn(helpers, 'sumNumber').and.returnValue(2)
// always return the value 2 when sumNumbers is executed

// also track how many times it was invoked

expect(helpers.sumNumber).toHaveBeenCalledTimes(2);
// called twice // check with what parameters it was called
expect(helpers.sumNumber).toHaveBeenCalledWith([1, 2]);
// 1 as a, 2 as b

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

Angular 5 does not recognize the function submitEl.triggerEventHandler, resulting in an error

Greetings! I am currently working on writing unit test cases in Angular5 Jasmine related to submitting a form. Below is the structure of my form: <form *ngIf="formResetToggle" class="form-horizontal" name="scopesEditorForm" #f="ngForm" novalidate (ngSu ...

Tips for specifying a variable as a mandatory key attribute within an array

Is there a way to dynamically determine the type of key attribute in an array? const arr = [ { key: 'a' }, { key: 'b' }, { key: 'c' }, ]; type key = ??? // Possible values for key are 'a', 'b', or &a ...

Tips for running batch files prior to debugging in VS Code

Currently, I am working on a project using Typescript, nodeJS, and VS Code. When it comes to debugging in VS Code, I have set up configurations in my launch.json file. { "type": "node", "request": "launch", "name": "La ...

Passing data between parent and child components within an Angular application using mat tab navigation

I am currently working on a project, which can be found at this link. Current Progress: I have implemented a mat tab group with tabs inside the app-component. When a tab is clicked, a specific component is loaded. Initially, most of the data is loaded in ...

Tips for implementing a real-time search feature in Angular

I require assistance. I am attempting to perform a live search using the following code: when text is entered into an input, I want my targetListOptions array, which is used in a select dropdown, to update accordingly. The code runs without errors, but not ...

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'), ...

Display or conceal elements within a Component with the help of a Service

After developing a custom Tabs component, I have implemented it in the following way (StackBlitz example): <tabs> <tab title="Tab 1"> <div toolbar> <message><span>Message 1: </span></message> &l ...

What is the reason behind the absence of a hide/show column feature in the Kendo Grid for Angular?

In my Angular application, I have implemented a Kendo Grid for Angular with the columnMenu feature enabled. This feature allows users to hide/show columns from a popup: Surprisingly, upon checking the ColumnMenu documentation, I noticed that there are no ...

I'm curious if someone can provide an explanation for `<->` in TypeScript

Just getting started with TypeScript. Can someone explain the meaning of this symbol <->? And, is ProductList actually a function in the code below? export const ProductList: React.FC<-> = ({ displayLoader, hasNextPage, notFound, on ...

Dynamically change or reassign object types in TypeScript

Check out the example you can copy and test in TypeScript Playground: class GreetMessage { message: {}; constructor(msg: string) { let newTyping: { textMsg: string }; // reassign necessary this.message = newTyping; this.message.textMsg = msg; ...

List component in Angular not refreshing after sorting the array in the service

Currently, I am delving into the realm of Angular (version 5+) to enhance my skills by working on a small project. The project involves setting up basic routing functionalities to showcase the ContactList component upon selecting a navigation tab. Addition ...

Discover the use of dot notation for accessing nested properties

In the deps array below, I aim to enforce type safety. Only strings allowed should be in dot notation of ${moduleX}.${moduleX service} // Modules each have a factory function that can return a services object (async) createModules({ data: { factory: ...

Facing issues during the unit testing of an angular component method?

I'm facing an issue with a unit test that is failing. Below is the code for reference: Here is my typescript file: allData: any; constructor(@Inject(MAT_DIALOG_DATA) private data, private dialogRef: MatDialogRef<MyComponent>, priva ...

Using local fonts with Styled Components and React TypeScript: A beginner's guide

Currently, I'm in the process of building a component library utilizing Reactjs, TypeScript, and Styled-components. I've come across the suggestion to use createGlobalStyle as mentioned in the documentation. However, since I am only working on a ...

React with TypeScript: The struggle of getting LocalStorage to work

Currently, I am dealing with persistence in a todo application developed using React and TypeScript. To achieve the desired persistence, I have implemented localStorage. Allow me to share some code snippets: const [todos, setTodos] = useState<todoMod ...

Receiving undefined when subscribing data to an observable in Angular

Currently, I am facing an issue in my Angular project where subscribing the data to an observable is returning undefined. I have a service method in place that retrieves data from an HTTP request. public fetchData(): Observable<Data[]> { const url = ...

Classname fails to modify the base style of the AppBar

Struggling to modify the appearance of the AppBar component by utilizing the className attribute, however, the .MuiAppBar-root class consistently takes precedence. const useStyles = makeStyles((theme: Theme) => ({ appBar: { backgroundColor: &apos ...

Implementing Angular WebSocket to showcase elements in a sequential manner during chat

Currently, I am developing a chat application using Angular and socket.io. The server can send multiple events in rapid succession, and the front end needs to handle each event sequentially. // Defining my socket service message: Subject<any> = new S ...

react-i18next: issues with translating strings

I encountered a frustrating issue with the react-i18next library. Despite my efforts, I was unable to successfully translate the strings in my application. The relevant code looked like this: App.tsx: import i18n from 'i18next'; import { initR ...

Detection of scanner devices in Angular 2 and above

Looking for a way to integrate UPC scanning functionality into my input box. When a user scans the UPC with a handheld scanner, I need it to trigger an automatic search function. However, if the UPC is manually entered via keyboard, I want the user to have ...