LoginSignup
2
2

More than 5 years have passed since last update.

finallyオペレータを含むObservableのテストを書く

Posted at

やりたいこと

こんな感じのコードがあった。

wantToDo.js
// DB操作を伴うとかそういう系のイメージ

const Observable = require("rxjs/Rx").Observable;
const { map, finalize, catchError } = require("rxjs/operators");

function foo (val) {
  console.log("foo!");
  return val;
}

// connection closeは常にしたいとか
function teardown () {
  console.log("teardown!");
}

// エラーが起きたときだけrollbackしたいだとか
function whenError(err) {
  console.log("some process...");
  throw err;
}

function wantToDo () {
  return Observable.from([1, 2, 3]).pipe(
    finalize(() => teardown()),
    map((val) => foo(val)),
    catchError((err) => whenError(err)),
  );
}

module.exports = { 
  wantToDo,
  foo,
  teardown,
  whenError,
};

index.js
wantToDo().subscribe((val) => console.log("some logic..."));

wantTodo()関数に対してこんな項目をテストしたくなった。

  • 正常系で、最後にteardownが呼ばれたか。
  • 異常系でも、最後にteardownが呼ばれたか。
  • 異常系のときは、whenErrorも呼ばれたか。

とりあえずテスト書いてみる。

こんなん書きました。

spec.js
it("should call teardown", () => {
  // arrange
  sinon.spy(teardown); // 多分これじゃ動かないけど、teardownをスパイしたとして。

  // act & assert
  wantToDo().subscribe(
    (val) => {},
    (err) => expect.fail(),
    () => expect(teardown.called).to.be.true,  // コケる...
  );
});

ハマりました。
rxjs/operatorsのfinalizeについて説明を見ると、こう書いてました。

Returns an Observable that mirrors the source Observable, but will call a specified function when the source terminates on complete or error.
(RxJS API Document)

finalizeに書いたものは、Subscriptionがcompleteもしくはerrorで閉じた後に実行されるんですね。

書き直し。

これでちゃんとテストできました。

spec.js
it("should call teardown", () => {
  // ...

  // act & assert
  wantToDo().subscribe(
    (val) => {},
    (err) => expect.fail(),
  ).add(() => expect(teardown.called).to.be.true);

Subscription.add()に書いたteardownメソッドは、finalizeに書いたものよりも後に実行されるようです。

でも問題もあって…。

テストが成功している間は大丈夫でした。
問題はコードを修正してテストが失敗したとき。

mocha -r -wとかで起動してさぁ修正…と思ったら。
テストに失敗したときにmochaのプロセスが落ちることがあるんですよね。
テスト起動し直すのめんどくせ…ってなりつつ、まだ解決策が見つかってません。
もし知ってる方がいれば教えてください。

2
2
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
2
2