LoginSignup
0
0

More than 1 year has passed since last update.

chaiのassertをtry-catchするときに注意!

Last updated at Posted at 2022-11-25

概要

AssertionErrorはtry-catchでcatchされるので気をつけましょう(自戒)という話です。
当たり前といえば当たり前かもしれません。。。

普通に失敗させる

tey-catchなしでassert.fail()させます。
AssertionErrorが発生して、結果はfailing(失敗)となります。

describe("test", () => {
  it("assertion without try-catch", () => {
    assert.fail("failed!!!");
  });
});
結果
  test
    1) assertion in try-catch

  0 passing (209ms)
  1 failing

  1) test
       assertion in try-catch:
     AssertionError: failed!!!

try-catchしてみる

assert.fail()をtryで囲って、catchします。
すると結果はpassing(成功)なります。
assert.fail()で発生したAssertionErrorがcatchされるためです。

describe("test", () => {
  it("assertion in try-catch", () => {
    try {
      assert.fail("failed!!!");
    } catch (e) {
      console.log("AssertionError is caught : " + e.message);
    }
  });
})

結果
  test
AssertionError is caught : failed!!!
    √ assertion in try-catch

  1 passing (221ms)

エラーが出ることをテストしたいこともあるよね

ここまではなんだか当たり前のような気がしますね。
ここからが本題です。(遅い)
異常系のテストでは正しくエラーが出ることを確かめたいのです。

次の例では、throwMyError()関数がエラーを出すことを確かめるテストをしようとしています。

describe("test", () => {
  it("an error occurs", () => {
    try {
      throwMyError();
      assert.fail("Failed because no error has occurred.");
    } catch (e) {
      //Success because an error occurred.
      console.log(e.message);
    }
  });

  const throwMyError = () => {
    throw new Error("My error has occurred.");
  };
});
結果
  test
My error has occurred.
    √ an error occurs

  1 passing (218ms)

エラーが出ればcatchされて成功していますね。
では、エラーが出なければassert.fail()で失敗するでしょうか?
試しにthrowMyError()でエラーを出さないようにしてみましょう。

describe("test", () => {
  it("an error occurs", () => {
    try {
      throwMyError();
      assert.fail("Failed because no error has occurred.");
    } catch (e) {
      //Success because an error occurred.
      console.log(e.message);
    }
  });

  const throwMyError = () => {
    console.log("We have no error...");
  };
});

結果
  test
We have no error...
Failed because no error has occurred.
    √ an error occurs

  1 passing (212ms)

というわけで成功していますね。
前述のとおり、assert.fail()が結局catchされてしまいます。

エラーがあることを確かめるテストの実装例

ここまでたどり着いた私たちはフラグを使うことにしました。
エラーの出るべきところでエラーが出なかったときに、hasErrorフラグをfalseに切り替えて、catchの外でフラグを見てassert.fail()とすることでAssertionErrorがcatchされることなく失敗となります。

describe("test", () => {
  it("an error occurs", () => {
    let hasError = true;
    try {
      throwMyError();
      hasError = false;
    } catch (e) {
      //Success because an error occurred.
      console.log(e.message);
    }
    if (!hasError) {
      assert.fail("Failed because no error has occurred.");
    }
  });

  const throwMyError = () => {
    console.log("We have no error...");
  };
});
結果
  test
We have no error...
    1) an error occurs

  0 passing (212ms)
  1 failing

  1) test
       an error occurs:
     AssertionError: Failed because no error has occurred.

今後気をつけます。以上自戒でした。

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