Skip to content

[Docs]: v30 Migration question re: SpyInstance #15637

@Stanzilla

Description

@Stanzilla

Page(s)

https://github.com/jestjs/jest/blob/main/docs/UpgradingToJest30.md

Description

The upgrade guide about SpyInstance is a bit unclear to me,

If you were using jest.SpyInstance in your TypeScript code (for instance, to annotate the return of jest.spyOn), you should update to using jest.Mock or the more specific jest.MockedFunction types.

but the types of SpyInstance do not work with MockedFunction? Is it the case that the whole SpyOn system changed?

If I want to continue using SpyOn which type should I use?

Example migration:

Image

Here is the whole file:

import React from 'react';
import { IntlProvider, IntlProviderService } from '..';
import { render } from '@testing-library/react';

type IntlProviderReturnType = ReturnType<IntlProvider['fetchLocaleMessages']>;
type IntlProviderParameters = Parameters<IntlProvider['fetchLocaleMessages']>;

type IntlProviderServiceReturnType = ReturnType<
  (typeof IntlProviderService)['updateLocaleMessages']
>;
type IntlProviderServiceParameters = Parameters<
  (typeof IntlProviderService)['updateLocaleMessages']
>;

describe('IntlProvider', () => {
  let fetchLocaleMessagesSpy: jest.SpyInstance<
    IntlProviderReturnType,
    IntlProviderParameters
  >;
  let updateLocaleMessagesSpy: jest.SpyInstance<
    IntlProviderServiceReturnType,
    IntlProviderServiceParameters
  >;

  beforeEach(() => {
    jest.clearAllMocks();
    fetchLocaleMessagesSpy = jest.spyOn(
      IntlProvider.prototype,
      'fetchLocaleMessages'
    );
    updateLocaleMessagesSpy = jest.spyOn(
      IntlProviderService,
      'updateLocaleMessages'
    );
  });

  afterEach(() => {
    jest.restoreAllMocks();
  });

  it('componentDidMount calls fetchLocaleMessages on mount', async () => {
    render(<IntlProvider>Test</IntlProvider>);

    expect(fetchLocaleMessagesSpy).toHaveBeenCalledTimes(1);
  });

  it('componentDidUpdate calls fetchLocaleMessages when the locale property change', async () => {
    const { rerender } = render(<IntlProvider locale="en">Test</IntlProvider>);
    expect(fetchLocaleMessagesSpy).toHaveBeenCalledTimes(1);
    expect(updateLocaleMessagesSpy).toHaveBeenCalledWith('en');

    rerender(<IntlProvider locale="pt">Test</IntlProvider>);

    expect(fetchLocaleMessagesSpy).toHaveBeenCalledTimes(2);
    expect(updateLocaleMessagesSpy).toHaveBeenCalledWith('pt');
  });

  it('componentDidUpdate not call fetchLocaleMessages when the locale property do not change', async () => {
    const { rerender } = render(<IntlProvider locale="en">Test</IntlProvider>);

    expect(fetchLocaleMessagesSpy).toHaveBeenCalledTimes(1);
    expect(updateLocaleMessagesSpy).toHaveBeenCalledWith('en');

    rerender(<IntlProvider locale="en">Test</IntlProvider>);

    expect(fetchLocaleMessagesSpy).toHaveBeenCalledTimes(1);
    expect(updateLocaleMessagesSpy).toHaveBeenCalledWith('en');
  });
});

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions