銀色うつ時間

思い出すたび何か胸につっかえてるだけ

Mockeryでモジュールをモックに差し替える

Mockeryを遣ってNode.jsのテストを書いている。requireしたモジュールをそのままモックに差し替えるとき、差し替えたいモジュールに渡されている文字列と全く同じものを渡す必要がある。差し替えるモジュールが標準ライブラリやnpm経由で取得してきたものであった場合はそのまま書けばよいが、自前のモジュールを相対パスなんかで呼び出しているときに気をつける。例えばこんな場面。

/lib/module.js

module.exports = {
  ouputMessage: () => {
    console.log('Hello from mod');
  }
};

/lib/foo.js

const module = require('./module.js');
module.outputMessage(); // Hello from mod

/lib/bar.js

const foo = require('./foo.js'); // Hello from mod

/test/index.js

const mockery = require('mockery');

describe('test', () => {

  before(() => {
    const mock = {
      outputMessage: () => {
        console.log('Hello from mock');
      }
    };
    mockery.registerMock('./module.js', mock);  // ここ
    mockery.enable({
      useCleanCache: true,
      warnOnUnregistered: false
    });
  });

  after(() => {
    mockery.deregisterMock('mod1');
    mockery.disable();
  });

  it('should say hello from mock', () => {
    const bar = require('../lib/bar.js') // Hello from mock
  });
});

テストコードからの相対パスではなく、モック化したいモジュールのパスをそのまま記述しないと動作しない。割と忘れて気づかないパターンが多い。

github.com

The arguments to registerMock are as follows:

module, the name or path of the module for which a mock is being registered. This must exactly match the argument to require; there is no “clever” matching.

はい😇