Wednesday, May 15, 2024
153
rated 0 times [  158] [ 5]  / answers: 1 / hits: 5887  / 2 Years ago, wed, november 2, 2022, 12:00:00

The following is an abstraction of my problem and thus does not make too much sense:


Given I have a simple utility callMethodIf that's returning the return of another imported method (blackbox).


~~/utils/call-method-if.js:


import { blackbox } from '~~/utils/blackbox';

export const callMethodIf = (condition) => {
return blackbox(condition);
};

~~/utils/blackbox.js:


export const blackbox = (condition) => {
return { called: condition };
};

How would I run one test case which calls the actual implementation of blackbox() and another one where I mock the return value of blackbox()?


I tried to do it that way:


import { describe, expect, it } from 'vitest';

import { callMethodIf } from '~~/utils/call-method-if';

describe('Call method if', () => {
it('returns "called: true" if condition is true', () => {
const result = callMethodIf(true);
expect(result).toEqual({ called: true });
});

it('returns mocked blackbox return object', () => {
vi.mock('~~/utils/blackbox', () => ({
blackbox: vi.fn().mockReturnValue({ mock: true })
}));
const result = callMethodIf(false);
expect(result).toEqual({ mock: true });
});
});

Both tests work if I run only one of them, but they don't work when combined.


Running vi.clearAllMocks() or vi.resetAllMocks() don't help.


Defining a global mock and overwriting it in my first test doesn't work either:


import { describe, expect, it } from 'vitest';

import { callMethodIf } from '~~/utils/call-method-if';

vi.mock('~~/utils/blackbox', () => ({
blackbox: vi.fn().mockReturnValue({ mock: true })
}));

describe('Call method if', () => {
it('returns "called: true" if condition is true', () => {
vi.mock('~~/utils/blackbox', async () => ({
blackbox: (await vi.importActual('~~/utils/blackbox')).blackbox
}));
const result = callMethodIf(true);
expect(result).toEqual({ called: true });
});

it('returns mocked blackbox return object', () => {
const result = callMethodIf(false);
expect(result).toEqual({ mock: true });
});
});

More From » unit-testing

 Answers
34

Okay, after lots of trial and error I finally got it to work. I can't really tell why my previous tries do not work tough.


Working solution:


import { describe, expect, it } from 'vitest';

import { callMethodIf } from '~~/utils/call-method-if';

vi.mock('~~/utils/blackbox');

describe('Call method if', () => {
it('returns "called: true" if condition is true', async () => {
const blackbox = await import('~~/utils/blackbox');
blackbox.blackbox = (await vi.importActual('~~/utils/blackbox')).blackbox;
const result = callMethodIf(true);
expect(result).toEqual({ called: true });
});

it('returns mocked blackbox return object', async () => {
const blackbox = await import('~~/utils/blackbox');
blackbox.blackbox = vi.fn().mockReturnValue({ mock: true });
const result = callMethodIf(false);
expect(result).toEqual({ mock: true });
});
});

When using TypeScript consider typing the importActual() return like that:


blackbox.blackbox = (await vi.importActual<typeof import('~~/utils/blackbox')>('~~/utils/blackbox')).blackbox;

[#17] Tuesday, August 2, 2022, 2 Years  [reply] [flag answer]
Only authorized users can answer the question. Please sign in first, or register a free account.
malkajillc

Total Points: 652
Total Questions: 107
Total Answers: 98

Location: Finland
Member since Sat, Nov 6, 2021
3 Years ago
malkajillc questions
Tue, Jun 29, 21, 00:00, 3 Years ago
Fri, Aug 21, 20, 00:00, 4 Years ago
Tue, Aug 11, 20, 00:00, 4 Years ago
Tue, Apr 14, 20, 00:00, 4 Years ago
;