1. ホーム
  2. javascript

[解決済み] ジャスミンクロックの仕組み

2022-02-16 03:19:12

質問

関連する部分を見つけるために何時間もコードを読みたくないのですが、jasmineがどのようにクロックを実装しているのか気になります。jasmineの面白いところは、非同期コードを同期テストコードでテストできることです。ES5をサポートする現在のnode.jsでは、これは不可能です(async関数はES7で定義されています)。estraverseのようなものでjsコードを解析し、同期ものから非同期テストを構築するのでしょうか?

ほんの一例ですが。

it("can test async code with sync testing code", function () {
    jasmine.clock().install();

    var i = 0;
    var asyncIncrease = function () {
        setTimeout(function () {
            ++i;
        }, 1);
    };

    expect(i).toBe(0);
    asyncIncrease();
    expect(i).toBe(0);
    jasmine.clock().tick(2);
    expect(i).toBe(1);

    jasmine.clock().uninstall();
});

この中で expect(i).toBe(1); はコールバックの中にあるはずです。

解決方法は?

その install() 関数は、実際には setTimeout を、jasmineがよりコントロールしやすいようにモック関数に置き換えたものです。これにより、実際の待ち時間が発生しないため、同期的に動作します。その代わり、手動で tick() 関数があり、これも同期的です。

ソースコードをご覧ください。 https://github.com/jasmine/jasmine/blob/ce9600a3f63f68fb75447eb10d62fe07da83d04d/src/core/Clock.js#L21

内部で5時間のタイムアウトを設定する関数があったとします。Jasmineはその関数を setTimeout を呼び出すと、そのコールバックが呼び出されるようにします。 tick() で、内部カウンタが5時間以上となるようにします。とてもシンプルですね。