What are the conditions for Jasmine's .toHaveBeenCalledWith to match the parameters?

I'm working on an Angular service along with its Jasmine test. The test is calling f1() and spying on f2(). The function f2 takes a variable v2 and updates it by setting field 'a' to 3. I expected the function f2 to be called with v2 (as defined in f1) but my test fails on toHaveBeenCalledWith and shows that the actual call was made with the object as it appears after the f2 function call. Is Jasmine checking the parameters for .toHaveBeenCalledWith after the function call, which might not be the recommended approach, or am I missing something here?

Service:

export class JasmineTestClass{
    constructor(){
    }
    f2(v2){
        v2.a = 3
    };
    f1(v1){
        let v2 = {
            a:30
        };
        this.f2(v2);
    }
}

Test:

describe('Test', () => {
    let service: JasmineTestClass;
    beforeEach(() => {
        service = new JasmineTestClass();
        spyOn(service, 'f2').and.callThrough();
    });
    let v1 = {
        a:2, b:3
    };
    let v2 = {
        a:30
    };
    it('should succeed', () => {
        service.f1(v1);
        expect(service.f2).toHaveBeenCalledWith(v2);    //this is failing
    });
})

Log:

Test should succeed FAILED

Expected spy f2 to have been called with [Object ({a:30})] but actual calls were [Object ({a:3})]

Also, note that I debugged in Chrome while testing and confirmed that the function f2() is indeed being called with v2 = {a:30}.

Answer №1

When asserting, <code>toHaveBeenCalledWith
matches the call arguments.

Jasmine spies store argument references internally, allowing call arguments to be traced by logging the service.f2.calls.all() object.

An issue arises with f2 as it alters the object passed by reference to it. The original v2 with v2.a === 30 is no longer present after the f2 call.

In such scenarios, creating specific tests for each unit (method) is recommended. If callThrough is used, it suggests that units are not isolated; in this case, using spyOn(service, 'f2') as a stub by default is preferable:

it('should succeed', () => {
  service.f1(v1);
  expect(service.f2).toHaveBeenCalledWith({ a:30 });
});

it('should succeed', () => {
  const obj = { a:30 };
  service.f2(obj);
  expect(obj).toEqual({ a:3 });
});

This approach allows for a more detailed examination of the functionality within these two methods.

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

"Error message: TypeORM DataSource encounters a password issue with the client

Here is the content of my data-source.ts file: import {DataSource} from "typeorm"; import path from "path"; import {User} from "./entity/User"; import { config } from "dotenv"; config(); export const AppDataSource ...

Utilizing the relativeTo method within a guard across various feature modules

I am facing a challenge with two lazily loaded Feature Modules that have a similar flow consisting of Select, Review, and Confirm steps. I want to create a single Guard for the Review step that can navigate back to Select based on the current Module contex ...

The attribute 'prop' is not found on the type 'IntrinsicAttributes & TableProp'.ts(2322)

Encountering an error while trying to pass a prop to a React component for the first time. Despite looking at other posts for solutions, I have been unable to resolve it so far. Here is a snippet of my code: type TableProp = {}; function Table(prop: Tabl ...

How can typescript configurations be imported/exported in a node environment?

I'm encountering difficulties while trying to set up a TypeScript node project and import modules: Below is the structure of my project: /build /src main.ts ...

Incorporating Angular views as peer components within the current view

I am currently working on implementing this HTML structure: <tr *ngFor="let row of rows"> <expandable-tree-row [columns]="cols" [data]="row"></expandable-tree-row> </tr> Within the ExpandableTreeRo ...

Firebase Cloud Function Local Emulator Fails to Retrieve Data with Error 404

My goal is to locally trigger a Firebase Cloud Function using the emulator. However, every time I try, the function returns a 404 Not Found status code and a response body of Cannot Get. The function is deployed locally and visible on the UI, but it fails ...

Can you guide me on implementing AWS SDK interfaces in TypeScript?

Attempting to create an SES TypeScript client using AWS definitions file downloaded from this link My approach so far: /// <reference path="../typings/aws-sdk.d.ts" /> var AWS = require('aws-sdk'); var ses:SES = new AWS.SES(); The error ...

What are some best practices for implementing pagination using Angular Material?

While following a tutorial by Muhi Masri on how to implement an Editable Dynamic Table using Angular Material Paginator (the tutorial can be found here, highly recommended), I encountered an issue where the paginator was not working as expected. Despite fo ...

Pause and be patient while in the function that delivers an observable

I have a function that loads user details and returns an observable. This function is called from multiple places, but I want to prevent redundant calls by waiting until the result is loaded after the first call. Can anyone suggest how this can be accompli ...

Angular 2/4 - Saving User Object Information in the Front-End Instead of Repeatedly Contacting the Back-End Server

Is there a more efficient way to store and update the current user details in the frontend, without constantly making new HTTP GET requests to the backend every time a new component loads? The solution I came up with is a UserService class that handles se ...

Executing the pause() function of NgbCarousel in Angular 5 when calling ngOnInit

I recently started learning Angular and using ngbootstrap for my UI development. I am facing an issue with loading the NgbCarousel in pause mode by default. Below is the code snippet that I have attempted: import { Component, OnInit, ViewChild } from ...

What is the method for locating an element within an array?

The content being returned is presenting a challenge. How can I retrieve data from inside 0? I attempted to access it using date[0] without success const { data } = getData(); The result of console.log(data) is shown below: enter image description here ...

Creating a multi-level signup page in Angular 4 using Bootstrap

Currently, I am working with angular 4 and bootstrap 4 to create a multi-level sign-up page. One of the challenges I am encountering is how to properly include a JavaScript file into my angular project. import '../../../assets/js/js/multiform.js&apo ...

An issue arose while compiling the template for 'AppRoutingModule', indicating that function expressions are not compatible with decorators

Currently, I have implemented the "CaseInsensitiveMatcher" based on the solution suggested by Alireza. However, I am facing an issue when attempting to create a production build as indicated by the following error message: "'urlMatch' referenc ...

The type of 'data' is assumed to be 'any[]' without being explicitly stated

I am encountering several type errors in the function below, and as a newcomer to Typescript, I'm unsure about how to fix them. private fetchFromUrl = () => { var data = [] fetch(`${process.env.PUBLIC_URL}/tempData/monthly.csv`) .t ...

Nest may struggle with resolving dependencies at times, but rest assured they are indeed present

I've encountered a strange issue. Nest is flagging a missing dependency in a service, but only when that service is Injected by multiple other services. cleaning.module.ts @Module({ imports: [ //Just a few repos ], providers: [ ServicesService, ...

Calling a function within another function

In my code, I have a function that formats the price and retrieves the value needed for refactoring after upgrading our dependencies. I'm struggling with passing the form value to the amountOnBlur function because the blur function in the dependencie ...

Splitting Files into Separate Directories in Angular 7

Currently, I am in the process of setting up my Angular 7 application for production and reorganizing files into different directories. angular.json "architect": { "build": { "builde ...

Having trouble accessing child pages using the router

In my Angular 2 application, I have implemented navigation successfully with the following routes: { path: 'layer1/layer2', component: C2 } } { path: 'layer1/layer2/layer3', component: C3, canDeactivate: [CanDeactivateGuard] } }, With ...

The 'MutableRefObject<null>' type is lacking the following properties that are present in the 'Element' type

I'm eager to implement intersection observer in my React Typescript project. (https://www.npmjs.com/package/react-intersection-observer) However, I encountered an issue with setting the root: const root = useRef(null); const { ref, inView, entry } ...