1

I'm trying to spy on a function that come from uuidv4 package but I didn't figure out how to do that.

This is my User Class:

import { uuid } from 'uuidv4';
import { IUser } from '../interfaces/IUser';

export class User implements IUser {
  constructor(
    public name: string,
    public email: string,
    public password: string,
    public id?: string,
  ) {
    this.id = id ? id : uuid();
  }
}

What I'm trying to do is spy on that uuid() method that is called on the constructor of the User.ts. I tried something like this:

import { User } from './User';

describe('User', () => {
  it('should call uuid() when no id is provided', () => {
    const sut = new User('Foo', 'foo@bar.com', '12345');
    const spy = jest.spyOn(sut, 'uuid');
    expect(spy).toHaveBeenCalledTimes(1);
  });
});

But it didn't work. Anyone knows how could I do this?

Lin Du
  • 88,126
  • 95
  • 281
  • 483
  • The spyOn spies on the exact function object not the imported function as a whole. It takes the function to spy on, wraps it with the spy and places it in the place of the old function. If now the function gets called, the spy knows. – CptPiepmatz May 05 '22 at 16:45
  • `uuid` (the function) is not a property of `sut`, so you can't spy on it. You can load the module in question in your test code, replace the function with a spy, and then run your test (the module is cached, so the sut gets the spy rather than the original). take care to remove the spy after use, or it could upset your other tests. – Dave Meehan May 05 '22 at 17:29
  • https://www.chakshunyu.com/blog/how-to-mock-only-one-function-from-a-module-in-jest/ – Dave Meehan May 05 '22 at 17:29

1 Answers1

0

You don't need to mock or install spy on the uuid to test the implementation detail. You can test the with Using a regular expression to check user.id is a UUID v4 or not.

Using a regular expression:

If you want to perform the verification on your own using a regular expression, use the regex property, and access its v4 or v5 property

index.ts:

import { uuid } from 'uuidv4';

interface IUser {
  id?: string;
}

export class User implements IUser {
  constructor(public name: string, public email: string, public password: string, public id?: string) {
    this.id = id ? id : uuid();
  }
}

index.test.ts:

import { User } from './';
import { regex } from 'uuidv4';

describe('User', () => {
  it('should call uuid() when no id is provided', () => {
    const user = new User('Foo', 'foo@bar.com', '12345');
    expect(regex.v4.test(user.id!)).toBeTruthy();
  });
});
 PASS  stackoverflow/72130740/index.test.ts (13.885 s)
  User
    ✓ should call uuid() when no id is provided (2 ms)

Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        16.53 s

Also take a look at the uuid test case

Lin Du
  • 88,126
  • 95
  • 281
  • 483