当記事におけるJavaScriptのコードは、クライアントサイドで動くことを想定されているものとします。
Jasmineのversionは 3.0
以上とします(3.0未満に関しては特に動作を確認してないため)。
関数内にglobal変数が入っている場合にテストを行う事態に遭遇し、そのときにおこなった方法の備忘録です。
通常の場合
JavaScriptで以下の関数をテストしたいとします。
...
function add(x, y){
return x + y;
}
...
このとき、add
関数に対するテストは以下の様に書くことができます。
describe("calcのテスト", function() {
it("1 + 2 は 3", function() {
expect(add(1,2)).toBe(3);
})
});
テスト対象のjsの関数がこのようになっていればいいのですが、レガシーコード(テストがないコード)に触れていると、関数内に関数内で未定義の変数が入っている場合があります。
関数内に未定義の変数がある場合
さて、以下のような関数があったとします。
...
function add(x, y){
return (x + y) * coef;
}
...
このcoef
という変数ですが、add
関数の内部では定義していません。
簡略化してますが、実際のところ、いろんな歴史的な経緯により、100行くらいの関数内の各所に coef
のような変数が埋まっていて、困った経験はあるのではないでしょうか?
この関数に対するテストとして以下の様なコードを試しに書いてみます。
describe("calcのテスト", function() {
it("1 + 2 は 3", function() {
const coef = 0.1;
expect(add(1,2)).toBe(0.3);
})
});
そして、jasmineを実行してみると、
ReferenceError: coef is not defined
となり、動きません。これは当然で、 coef
のスコープが、it内の範囲しか適用されず、add
関数では未定義となるためです。
テストを正常に動かす方法として以下の様にすれば動きます。
describe("calcのテスト", function() {
it("1 + 2 は 3", function() {
coef = 0.1;
expect(add(1,2)).toBe(0.3);
})
});
このcoef
ですが、window直下のオブジェクトとして定義されています。
この副作用として、 1 + 2 は 3
というテストケース以降のテストにおいては、 window直下に coef
は定義されてままの状態になってしまいます。
実際のテストにおいては、 window.coef
ということを明示しておくと、可読性が高いかと思います。
describe("calcのテスト", function() {
it("1 + 2 は 3", function() {
window.coef = 0.1;
expect(add(1, 2)).toBe(0.3);
})
});