Можно ли написать модульные тесты Jest для Node.js fs.readFile ()? - PullRequest
0 голосов
/ 12 ноября 2019

Я новичок в модульном тестировании Jest, и мне было интересно, можно ли использовать Jest для тестирования модулей файловой системы Node.js.

В настоящее время у меня есть текстовый файл, который содержит короткое стихотворение, и консоль функции viewText записывает это стихотворение на моем терминале.

Используя Jest, я хочу написать тест, который проверяет,viewText функция действительно работает.

const viewText = () => {
  fs.readFile('poem.txt', 'utf8', (err, data) => {
    if (err) throw err;
    console.log(data);
  });
};

С помощью Jest я попытался:

jest.spyOn(global.console, 'log');

const mockPoem = 'Some say the world will end in fire, Some say in ice. From what I’ve tasted of desire I hold with those who favor fire ... And would suffice.';

describe('viewText', () => {
  const mockReadFile = jest.fn();
  mockReadFile.mockReturnValue(mockPoem);

  it('prints poem to console', () => {
    viewText();
    expect(global.console.log).toHaveBeenCalledWith(mockPoem);
  });
});

С помощью теста все, что я хочу сделать, проверить, прошла ли моя функция viewTextтест - уметь просматривать mockPoem. Я действительно смущен тем, как мне следует подходить к написанию модульных тестов для функций с использованием модуля файловой системы.

1 Ответ

0 голосов
/ 12 ноября 2019

Вот решение UT:

index.ts:

import fs from 'fs';

export const viewText = () => {
  fs.readFile('poem.txt', 'utf8', (err, data) => {
    if (err) throw err;
    console.log(data);
  });
};

index.spec.ts:

import { viewText } from './';
import fs from 'fs';

const mockPoem =
  'Some say the world will end in fire, Some say in ice. From what I’ve tasted of desire I hold with those who favor fire ... And would suffice.';

describe('viewText', () => {
  afterEach(() => {
    jest.restoreAllMocks();
  });
  test('prints poem to console', done => {
    const logSpy = jest.spyOn(console, 'log');
    let readFileCallback;
    // @ts-ignore
    jest.spyOn(fs, 'readFile').mockImplementation((path, options, callback) => {
      readFileCallback = callback;
    });

    viewText();
    readFileCallback(null, mockPoem);
    expect(logSpy).toBeCalledWith(mockPoem);
    expect(fs.readFile).toBeCalledWith('poem.txt', 'utf8', readFileCallback);
    done();
  });

  test('should throw error when read file failed', done => {
    let readFileCallback;
    // @ts-ignore
    jest.spyOn(fs, 'readFile').mockImplementation((path, options, callback) => {
      readFileCallback = callback;
    });

    viewText();
    const mError = new Error('read file failed');
    expect(() => readFileCallback(mError, null)).toThrowError(mError);
    expect(fs.readFile).toBeCalledWith('poem.txt', 'utf8', readFileCallback);
    done();
  });
});

Результат модульного теста со 100% покрытием:

 PASS  src/stackoverflow/58810079/index.spec.ts (11.118s)
  viewText
    ✓ prints poem to console (23ms)
    ✓ should throw error when read file failed (3ms)

  console.log node_modules/jest-mock/build/index.js:860
    Some say the world will end in fire, Some say in ice. From what I’ve tasted of desire I hold with those who favor fire ... And would suffice.

----------|----------|----------|----------|----------|-------------------|
File      |  % Stmts | % Branch |  % Funcs |  % Lines | Uncovered Line #s |
----------|----------|----------|----------|----------|-------------------|
All files |      100 |      100 |      100 |      100 |                   |
 index.ts |      100 |      100 |      100 |      100 |                   |
----------|----------|----------|----------|----------|-------------------|
Test Suites: 1 passed, 1 total
Tests:       2 passed, 2 total
Snapshots:   0 total
Time:        13.129s

Исходный код: https://github.com/mrdulin/jest-codelab/tree/master/src/stackoverflow/58810079

...