Security News
GitHub Removes Malicious Pull Requests Targeting Open Source Repositories
GitHub removed 27 malicious pull requests attempting to inject harmful code across multiple open source repositories, in another round of low-effort attacks.
vitest-mock-extended
Advanced tools
Type safe mocking extensions for vitest, forked from jest-mock-extended
The vitest-mock-extended package provides utilities for creating mocks, spies, and stubs in the Vitest testing framework. It is designed to simplify the process of mocking dependencies and verifying interactions in unit tests.
Creating Mocks
This feature allows you to create a mock object based on an interface or type. You can then define the behavior of the mock's methods and properties.
const { mock } = require('vitest-mock-extended');
const myMock = mock<MyInterface>();
myMock.someMethod.mockReturnValue('mocked value');
// Usage in a test
expect(myMock.someMethod()).toBe('mocked value');
Spying on Functions
This feature allows you to create a spy on an existing function. You can then define the behavior of the spied function and verify its interactions.
const { spyOn } = require('vitest-mock-extended');
const myObject = { myMethod: () => 'real value' };
const spy = spyOn(myObject, 'myMethod');
spy.mockReturnValue('spied value');
// Usage in a test
expect(myObject.myMethod()).toBe('spied value');
expect(spy).toHaveBeenCalled();
Stubbing Methods
This feature allows you to create a stub for a method. You can define the return value or behavior of the stubbed method.
const { stub } = require('vitest-mock-extended');
const myStub = stub<MyInterface>();
myStub.someMethod.returns('stubbed value');
// Usage in a test
expect(myStub.someMethod()).toBe('stubbed value');
Sinon is a popular standalone test spies, stubs, and mocks library for JavaScript. It provides similar functionalities to vitest-mock-extended but is framework-agnostic, meaning it can be used with any testing framework, not just Vitest.
Jest Mock is a part of the Jest testing framework that provides utilities for creating mocks, spies, and stubs. It offers similar functionalities to vitest-mock-extended but is specifically designed to work with Jest.
Testdouble is a library for creating test doubles (mocks, stubs, and spies) in JavaScript. It provides a flexible API for defining and verifying interactions, similar to vitest-mock-extended, but can be used with various testing frameworks.
Type safe mocking extensions for Vitest ✅
THIS IS A FORK OF jest-mock-extended ALL CREDITS GO TO THE ORIGINAL AUTHOR
npm install vitest-mock-extended --save-dev
or
yarn add vitest-mock-extended --dev
If ReferenceError: vi is not defined
related error occurs, please set globals: true
.
import { mock } from 'vitest-mock-extended';
interface PartyProvider {
getPartyType: () => string;
getSongs: (type: string) => string[];
start: (type: string) => void;
}
describe('Party Tests', () => {
test('Mock out an interface', () => {
const mock = mock<PartyProvider>();
mock.start('disco party');
expect(mock.start).toHaveBeenCalledWith('disco party');
});
test('mock out a return type', () => {
const mock = mock<PartyProvider>();
mock.getPartyType.mockReturnValue('west coast party');
expect(mock.getPartyType()).toBe('west coast party');
});
test('Can specify fallbackMockImplementation', () => {
const mockObj = mock<MockInt>(
{},
{
fallbackMockImplementation: () => {
throw new Error('not mocked');
},
}
);
expect(() => mockObj.getSomethingWithArgs(1, 2)).toThrowError('not mocked');
});
});
If you wish to assign a mock to a variable that requires a type in your test, then you should use the MockProxy<> type given that this will provide the apis for calledWith() and other built-in vitest types for providing test functionality.
import { MockProxy, mock } from 'vitest-mock-extended';
describe('test', () => {
let myMock: MockProxy<MyInterface>;
beforeEach(() => {
myMock = mock<MyInterface>();
})
test(() => {
myMock.calledWith(1).mockReturnValue(2);
...
})
});
vitest-mock-extended
allows for invocation matching expectations. Types of arguments, even when using matchers are type checked.
const provider = mock<PartyProvider>();
provider.getSongs.calledWith('disco party').mockReturnValue(['Dance the night away', 'Stayin Alive']);
expect(provider.getSongs('disco party')).toEqual(['Dance the night away', 'Stayin Alive']);
// Matchers
provider.getSongs.calledWith(any()).mockReturnValue(['Saw her standing there']);
provider.getSongs.calledWith(anyString()).mockReturnValue(['Saw her standing there']);
You can also use mockFn()
to create a vi.fn()
with the calledWith extension:
type MyFn = (x: number, y: number) => Promise<string>;
const fn = mockFn<MyFn>();
fn.calledWith(1, 2).mockReturnValue('str');
vitest-mock-extended
exposes a mockClear and mockReset for resetting or clearing mocks with the same
functionality as vi.fn()
.
import { mock, mockClear, mockReset } from 'vitest-mock-extended';
describe('test', () => {
const mock: UserService = mock<UserService>();
beforeEach(() => {
mockReset(mock); // or mockClear(mock)
});
...
})
If your class has objects returns from methods that you would also like to mock, you can use mockDeep
in
replacement for mock.
import { mockDeep } from 'vitest-mock-extended';
const mockObj: DeepMockProxy<Test1> = mockDeep<Test1>();
mockObj.deepProp.getNumber.calledWith(1).mockReturnValue(4);
expect(mockObj.deepProp.getNumber(1)).toBe(4);
if you also need support for properties on functions, you can pass in an option to enable this
import { mockDeep } from 'vitest-mock-extended';
const mockObj: DeepMockProxy<Test1> = mockDeep<Test1>({ funcPropSupport: true });
mockObj.deepProp.calledWith(1).mockReturnValue(3);
mockObj.deepProp.getNumber.calledWith(1).mockReturnValue(4);
expect(mockObj.deepProp(1)).toBe(3);
expect(mockObj.deepProp.getNumber(1)).toBe(4);
Can can provide a fallback mock implementation used if you do not define a return value using calledWith
.
import { mockDeep } from 'jest-mock-extended';
const mockObj = mockDeep<Test1>({
fallbackMockImplementation: () => {
throw new Error('please add expected return value using calledWith');
},
});
expect(() => mockObj.getNumber()).toThrowError('not mocked');
Matcher | Description |
---|---|
any() | Matches any arg of any type. |
anyBoolean() | Matches any boolean (true or false) |
anyString() | Matches any string including empty string |
anyNumber() | Matches any number that is not NaN |
anyFunction() | Matches any function |
anyObject() | Matches any object (typeof m === 'object') and is not null |
anyArray() | Matches any array |
anyMap() | Matches any Map |
anySet() | Matches any Set |
isA(class) | e.g isA(DiscoPartyProvider) |
includes('value') | Checks if value is in the argument array |
containsKey('key') | Checks if the key exists in the object |
containsValue('value') | Checks if the value exists in an object |
has('value') | checks if the value exists in a Set |
notNull() | value !== null |
notUndefined() | value !== undefined |
notEmpty() | value !== undefined && value !== null && value !== '' |
captor() | Used to capture an arg - alternative to mock.calls[0][0] |
Custom matchers can be written using a MatcherCreator
import { MatcherCreator, Matcher } from 'vitest-mock-extended';
// expectedValue is optional
export const myMatcher: MatcherCreator<MyType> = (expectedValue) =>
new Matcher((actualValue) => {
return expectedValue === actualValue && actualValue.isSpecial;
});
By default, the expected value and actual value are the same type. In the case where you need to type the expected value differently than the actual value, you can use the optional 2 generic parameter:
import { MatcherCreator, Matcher } from 'vitest-mock-extended';
// expectedValue is optional
export const myMatcher: MatcherCreator<string[], string> = (expectedValue) =>
new Matcher((actualValue) => {
return actualValue.includes(expectedValue);
});
FAQs
Type safe mocking extensions for vitest, forked from jest-mock-extended
We found that vitest-mock-extended demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
GitHub removed 27 malicious pull requests attempting to inject harmful code across multiple open source repositories, in another round of low-effort attacks.
Security News
RubyGems.org has added a new "maintainer" role that allows for publishing new versions of gems. This new permission type is aimed at improving security for gem owners and the service overall.
Security News
Node.js will be enforcing stricter semver-major PR policies a month before major releases to enhance stability and ensure reliable release candidates.