jest-mock-extended
    TypeScript icon, indicating that this package has built-in type declarations

    2.0.4 • Public • Published

    jest-mock-extended

    Type safe mocking extensions for Jest 🃏

    Build Status Coverage Status npm version License: MIT npm downloads

    Features

    • Provides complete Typescript type safety for interfaces, argument types and return types
    • Ability to mock any interface or object
    • calledWith() extension to provide argument specific expectations, which works for objects and functions.
    • Extensive Matcher API compatible with Jasmine matchers
    • Supports mocking deep objects / class instances.
    • Familiar Jest like API

    Installation

    npm install jest-mock-extended --save-dev

    or

    yarn add jest-mock-extended --dev

    Example

    import { mock } from 'jest-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');
       });
    });

    Assigning Mocks with a Type

    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 jest types for providing test functionality.

    import { MockProxy, mock } from 'jest-mock-extended';
    
    describe('test', () => {
        let myMock: MockProxy<MyInterface>;
    
        beforeEach(() => {
            myMock = mock<MyInterface>();
        })
    
        test(() => {
             myMock.calledWith(1).mockReturnValue(2);
             ...
        })
    });

    calledWith() Extension

    jest-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 jest.fn() with the calledWith extension:

     type MyFn = (x: number, y: number) => Promise<string>;
     const fn = mockFn<MyFn>();
     fn.calledWith(1, 2).mockReturnValue('str');

    Clearing / Resetting Mocks

    jest-mock-extended exposes a mockClear and mockReset for resetting or clearing mocks with the same functionality as jest.fn().

    import { mock, mockClear, mockReset } from 'jest-mock-extended';
    
    describe('test', () => {
       const mock: UserService = mock<UserService>();
       
       beforeEach(() => {
          mockReset(mock); // or mockClear(mock)
       });
       ...
    })

    Deep mocks

    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 'jest-mock-extended';
    
    const mockObj = mockDeep<Test1>();
    mockObj.deepProp.getNumber.calledWith(1).mockReturnValue(4);
    expect(mockObj.deepProp.getNumber(1)).toBe(4);

    Available Matchers

    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]

    Writing a Custom Matcher

    Custom matchers can be written using a MatcherCreator

    import { MatcherCreator, Matcher } from 'jest-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 'jest-mock-extended';
    
    // expectedValue is optional
    export const myMatcher: MatcherCreator<string[], string> = (expectedValue) => new Matcher((actualValue) => {
        return (actualValue.includes(expectedValue));
    });

    Keywords

    none

    Install

    npm i jest-mock-extended

    DownloadsWeekly Downloads

    202,720

    Version

    2.0.4

    License

    MIT

    Unpacked Size

    160 kB

    Total Files

    41

    Last publish

    Collaborators

    • marchaos