typescript - I Jest, hur mockar jag ett externt modul ENDAST i ett specifikt test?


Jag använder Jest med TypeScript (med ts-jest). Detta är mitt testobjekt som använder dotenv-biblioteket:

import * as dotenv from 'dotenv';

export class TestSubject {
  public function test() {
    console.log(dotenv); // Here I debug if I'm using a mock or not
  }
}

Jag skulle vilja mocka dotenv-biblioteket bara för ett specifikt test, men jag sitter fast.

Här är min testsvit:

import { TestSubject } from './test-subject';
import * as dotenv from 'dotenv';

jest.mock('dotenv'); // place it here, otherwise it doesn't work

describe('Suite 1', () => {
  it('test 1', () => {
    // I want to use the mock here... and it works
    const subject = new TestSubject();
    subject.test(); // shows that I'm using the mock
  });

  it('test 2', () => {
    // I don't want the mock here
    jest.dontMock('dotenv'); // doesn't work
    jest.unmock('dotenv');   // doesn't work

    const subject = new TestSubject();
    subject.test(); // shows that I'm still using the mock!!!
  });
});

Som du kan se, bör anropet jest.mock('dotenv') placeras utanför describe, annars fungerar det inte.

Jag försöker att inte använda mocken i test 2, men det fungerar inte: console.log visar att jag använder mocken.

Svar #1

En förbättring av @slideshowp2:s lösning.

Med jest.domock behöver du anropa require efter modulen (som här), men resultatet av require har typen any och vi förlorar typkontrollen. Så du kan använda Typescripts dynamiska imports.

Exempel på komplett kod:

import * as summer from './exampleModule';

describe('mock vs no-mock', () => {
    beforeEach(() => {
        jest.resetModules();
    });

    it('NO-MOCKED', async () => {
        console.log(summer.sum(1, 1));
        expect(summer.sum(1, 1)).toBe(2);
    });
    it('MOCKED', async () => {
        jest.doMock('./exampleModule');
        const summer = await import('./exampleModule');

        const mockedSummer = mocked(summer, true);
        mockedSummer.sum.mockImplementation((a, b) => a + b + 1);
        console.log(summer.sum(1, 1));
        expect(summer.sum(1, 1)).toBe(3);
    });
    it('NO-MOCKED', async () => {
        console.log(summer.sum(1, 1));
        expect(summer.sum(1, 1)).toBe(2);
    });
});

Svar #2

Här är lösningen:

index.ts, filen kommer att testas:

import * as dotenv from 'dotenv';

export class TestSubject {
  public test() {
    console.log(dotenv);
  }
}

Enhetstest:

describe('TestSubject', () => {
  beforeEach(() => {
    jest.resetModules();
  });
  it('should mock dotenv', () => {
    jest.doMock('dotenv');
    const dotenv = require('dotenv');
    const { TestSubject } = require('./');
    const subject = new TestSubject();
    subject.test();
    expect(jest.isMockFunction(dotenv.config)).toBeTruthy();
  });

  it('should not mock dotenv', () => {
    jest.unmock('dotenv');
    const dotenv = require('dotenv');
    const { TestSubject } = require('./');
    const subject = new TestSubject();
    subject.test();
    expect(jest.isMockFunction(dotenv.config)).toBeFalsy();
  });
});

Enhetstestresultat:

 PASS  src/stackoverflow/56446543/index.spec.ts
  TestSubject
    ✓ should mock dotenv (2111ms)
    ✓ should not mock dotenv (2ms)

  console.log src/stackoverflow/56446543/index.ts:5
    { config: 
       { [Function: config]
         _isMockFunction: true,
         getMockImplementation: [Function],
         mock: [Getter/Setter],
         mockClear: [Function],
         mockReset: [Function],
         mockRestore: [Function],
         mockReturnValueOnce: [Function],
         mockResolvedValueOnce: [Function],
         mockRejectedValueOnce: [Function],
         mockReturnValue: [Function],
         mockResolvedValue: [Function],
         mockRejectedValue: [Function],
         mockImplementationOnce: [Function],
         mockImplementation: [Function],
         mockReturnThis: [Function],
         mockName: [Function],
         getMockName: [Function] },
      parse: 
       { [Function: parse]
         _isMockFunction: true,
         getMockImplementation: [Function],
         mock: [Getter/Setter],
         mockClear: [Function],
         mockReset: [Function],
         mockRestore: [Function],
         mockReturnValueOnce: [Function],
         mockResolvedValueOnce: [Function],
         mockRejectedValueOnce: [Function],
         mockReturnValue: [Function],
         mockResolvedValue: [Function],
         mockRejectedValue: [Function],
         mockImplementationOnce: [Function],
         mockImplementation: [Function],
         mockReturnThis: [Function],
         mockName: [Function],
         getMockName: [Function] },
      default: 
       { config: 
          { [Function: config]
            _isMockFunction: true,
            getMockImplementation: [Function],
            mock: [Getter/Setter],
            mockClear: [Function],
            mockReset: [Function],
            mockRestore: [Function],
            mockReturnValueOnce: [Function],
            mockResolvedValueOnce: [Function],
            mockRejectedValueOnce: [Function],
            mockReturnValue: [Function],
            mockResolvedValue: [Function],
            mockRejectedValue: [Function],
            mockImplementationOnce: [Function],
            mockImplementation: [Function],
            mockReturnThis: [Function],
            mockName: [Function],
            getMockName: [Function] },
         parse: 
          { [Function: parse]
            _isMockFunction: true,
            getMockImplementation: [Function],
            mock: [Getter/Setter],
            mockClear: [Function],
            mockReset: [Function],
            mockRestore: [Function],
            mockReturnValueOnce: [Function],
            mockResolvedValueOnce: [Function],
            mockRejectedValueOnce: [Function],
            mockReturnValue: [Function],
            mockResolvedValue: [Function],
            mockRejectedValue: [Function],
            mockImplementationOnce: [Function],
            mockImplementation: [Function],
            mockReturnThis: [Function],
            mockName: [Function],
            getMockName: [Function] } } }

  console.log src/stackoverflow/56446543/index.ts:5
    { config: [Function: config],
      parse: [Function: parse],
      default: { config: [Function: config], parse: [Function: parse] } }

Test Suites: 1 passed, 1 total
Tests:       2 passed, 2 total
Snapshots:   0 total
Time:        3.394s, estimated 4s

Som du kan se är dotenv-modulen mockad för det första testfallet och är inte mockad för det andra testfallet.

Du kan hitta den färdiga demon här: https://github.com/mrdulin/jest-codelab/tree/master/src/stackoverflow/56446543

Relaterade artiklar