Tumgik
#proxyquire
chikuwa-parfait · 8 years
Text
モックテストについていくらか調べた
いままでJavaScriptでモックを使ったテストというとSinon.JSしか使ったことがなかった。 そこにReactのテストを書く必要がある事態になったのでいろいろ調べて試してみることに。ちなみにJestは使わない。
proxyquireについて
requireをフックしてインジェクションするモジュール。
b.js
module.exports = function() { console.log('Hello!'); };
a.js
var b = require('./b'); b();
index.js
require('./a');
上記3つのファイルがあるとして、index.jsを実行すると以下のようになる。
$ node index.js Hello!
ここでb.jsをproxyquireで別のモジュールとして置き換える。
index.js
var proxyquire = require('proxyquire'); var mock = function() { console.log('See you!'); }; // 第一引数にindex.jsでrequireの引数に渡す文字列を、 // 第二引数のキーにrequireされるモジュール内でrequireされる引数の文字列を渡す // どちらも完全一致している必要がある proxyquire('./a', { './b': mock }); require('./a');
これでindex.jsを実行すると結果が変わる。
$ node index.js See you!
また、proxyquireに渡す第二引数内に特殊なキーを指定すると、node_modules内から読み込まれるはずのものも置き換えることができる。
a.js
var deepcopy = require('deepcopy'); deepcopy();
index.js
var proxyquire = require('proxyquire'); var mock = function() { console.log('mock'); }; mock['@global'] = true; proxyquire('./a', { 'deepcopy': mock }); require('./a');
これで実行するとモジュールを置き換えられていることがわかる。
$ npm install deepcopy $ node index.js mock
ただ、Babelなどでimport文などを使用していると正常に動作しないようだ。
inject-loaderについて
webpackのloaderとして実装されている。当然ながらwebpackと一緒に使用する。
webpackのissueでもproxyquireの代わりのものとしてコメントされていた。
以下のコードはbabel-loaderも一緒に使用することを想定したもの。
mod.jsx
(空のファイル)
sample.jsx
import mod from './mod.jsx'; export default mod;
index.jsx
import sampleInjector from 'inject!./sample.jsx'; const sample = sampleInjector({ './mod.jsx': { method() { console.log('Hello!'); } } }).default; sample.method();
これでwebpackでコンパイルしたあとに実行すると以下のようになる。
$ node index.js Hello!
使いかたはproxyquireなどとほとんど似たような記述になる。
こちらはproxyquireと違ってimport文で書いても失敗しない。といっても結局は関数を呼んでいるのだが。
webpack内で使えるloaderなだけあって、externalsで指定した名前などでも置き換えられる。 おそらくaliasなども置き換えられると思う。
karma-webpackでも当然使えるので、今回はinject-loaderで解決した。というよりかはこれでないと解決できなかった。
0 notes