LoginSignup
1
1

【備忘録】Node.js向けテスト用モックライブラリ

Last updated at Posted at 2023-06-02

備忘録です。たまに忘れるので記録用に残しておきます。

mock-fs

最強のファイルシステム用モックライブラリです。これを使うことで、fsモジュールを使ったコードやライブラリを、実際のファイルシステムを使うこと無くテストすることができます。

const assert = require('node:assert/strict');
const fs = require('node:fs/promises');
const path = require('node:path');
const { test } = require('node:test');

const mockFs = require('mock-fs');

test('ファイルの読み込みをモックするテスト', async () => {
  try {
    mockFs({
      'anser.txt': '42',
    });

    const filepath = path.join(process.cwd(), 'anser.txt');
    const filedata = await fs.readFile(filepath, { encoding: 'utf8' });
    assert.strictEqual(filedata, '42');
  } finally {
    mockFs.restore();
  }
});

mock-fsが最強である理由は、これがECMAScript Modulesでも使える事です。嘘ではありません。Jestのjest.mock('fs');みたいなテストコードの動的書き換えすら要らず、Node.jsネイティブのESMでも使えます。試しに以下のコードを拡張子.mjsのファイルに保存してnodeコマンドで実行してみてください。

import * as assert from 'node:assert/strict';
import * as fs from 'node:fs/promises';
import * as path from 'node:path';
import { test } from 'node:test';

import mockFs from 'mock-fs';

test('ファイルの読み込みをモックするテスト', async () => {
  try {
    mockFs({
      'anser.txt': '42',
    });

    const filepath = path.join(process.cwd(), 'anser.txt');
    const filedata = await fs.readFile(filepath, { encoding: 'utf8' });
    assert.strictEqual(filedata, '42');
  } finally {
    mockFs.restore();
  }
});

これが可能なのは、mock-fsがfsモジュールではなく、fsモジュールが内部で使用しているinternalBinding('fs')を書き換えているからです。require('fs')はモックしていないので、ESMだろうと正しくモックできるというわけです。

これを知った時は心底驚いた。

nock

HTTP通信用のモックライブラリです。だいぶ前に見つけて以来、愛用しています。

spawk

サブプロセス用のモックライブラリです。child_processモジュールを使っているコードのテストに使えます。

vitest-mock-process / jest-mock-process

process.stdoutprocess.stderrconsole.log()用のモックライブラリです。名前の通り、VitestまたはJest向け。stdoutやstderrに何かを書き込む関数のテストに最適。

あとがき

  • ファイルシステム
  • HTTP通信
  • サブプロセス
  • stdoutとstderr

この4種類をモックできれば、大抵のテストコードで困ることは無いでしょう。個人的には困っていません。

モックというと、たいていのテストコードでは関数そのものやライブラリそのものをモックする方法がよく取られているように思います。しかし、依存しているライブラリの内部挙動が変更されたことでバグが発生することもあります。依存するライブラリの正しさを含めてこそのテスト。そう考えるならば、やはりNode.jsが提供するI/Oそのものをモックする方法が最適だと考えます。

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1