Jest: издевательства над сторонними модулями - PullRequest
2 голосов
/ 03 мая 2019

Недавно я пытался научиться юнит-тестированию с Jest, читая документы и различные статьи.

Одна вещь, которую я не смог выяснить, это следующее:

Iя пытаюсь протестировать модуль nodeJS с условным оператором if на os.platform().

Можно ли в моем тесте установить / смоделировать возвращаемое значение os.platform для чего-то другого, поэтому, когдаJest запускает тестовый файл, тестовый файл будет читать значение os.platform (), указанное в наборе тестов?

PS: foo() не может принять платформу через внедрение зависимостей.Реализация foo() исправлена.

myModule.js

import os from 'os';
export const foo = () => {
  if (os.platform() === `win32`) {
    module = module.split(`\\`).join(`\\\\`);
  }
}

myModule.test.js

import * as myModule from '../myModule.js';

// Guessing I need to use spyOn, to test the actual module code?
const myModuleMock = jest.spyOn(myModule, 'foo');

describe('myModule', () => {
  it('can run with different os.platform() values', () => {
    myModuleMock();
    expect(myModuleMock).toHaveBeenCalled();
    // How do I specify what value os.platform() in foo() should return?
  });
});

Ответы [ 2 ]

1 голос
/ 04 мая 2019

Вы можете импортировать os в свой тестовый файл и использовать jest.spyOn, чтобы смоделировать его следующим образом:

import * as myModule from '../myModule.js';
import os from 'os';

describe('myModule', () => {
  it('can run with different os.platform() values', () => {
    const spy = jest.spyOn(os, 'platform');
    spy.mockReturnValue('mocked response');  // <= mock the return value

    myModule.foo();

    expect(spy).toHaveBeenCalled();  // Success!
  });
});

Я предпочитаю этот подход, потому что он держит макет ближе к тесту, на который он влияет.


Если вы хотите использовать jest.mock с заводской функцией, вы можете сделать это следующим образом:

jest.mock('os', () => { 
  const os = jest.requireActual('os');
  jest.spyOn(os, 'platform').mockReturnValue('mocked response');
  return os;
});

Обратите внимание, что заводская функция должна быть полностью автономной.

1 голос
/ 03 мая 2019

Можно смоделировать модуль os, добавив файл os.js в __mocks__ dir:

// ./__mocks__/os.js
const os = jest.requireActual('os')

os.platform = jest.fn().mockReturnValue('testPlatform')
module.exports = os

// ./tests/whatever/some.test.js
import os from 'os'

jest.mock('os')

test('os', () => {
  expect(os.platform()).toBe('testPlatform') // ✔️
})

или, используя только один файл:

const mockOS = jest.requireActual('os')
mockOS.platform = jest.fn().mockReturnValue('testPlatform')
jest.mock('os', () => mockOS)

import os from 'os'

test('os', () => {
  expect(os.platform()).toBe('testPlatform')
})

поэтому ваш тестовый файл должен выглядеть примерно так:

const mockOS = jest.requireActual('os')
mockOS.platform = jest.fn().mockReturnValue('testPlatform')
jest.mock('os', () => mockOS)


import * as myModule from '../myModule.js';

describe('myModule', () => {
  it('can run with different os.platform() values', () => {
    myModuleMock();
    expect(myModuleMock).toHaveBeenCalled();
  });
});```
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...