LoginSignup
9
7

More than 5 years have passed since last update.

power-assertの例外処理を見やすくする

Last updated at Posted at 2016-04-01

power-assert is fully compatible with assert. So functions below are also available though they are not enhanced (does not produce descriptive message).

  • assert.fail(actual, expected, message, operator)
  • assert.throws(block, [error], [message])
  • assert.doesNotThrow(block, [message])
  • assert.ifError(value)

API - power-assert/v1.3.1/README.md

とあるように、assert.throwsはテスト失敗時に整形されません。

test.js
import assert from 'power-assert';

assert.throws(
  () => {
    throw new Error('foo');
  },
  /^bar$/
);
// Error: foo
//    at test.js:5:11

エラーメッセージの比較をしたいときは、以下のように書く必要があります。

test.js
import assert from 'power-assert';

assert.throws(
  () => {
    throw new Error('foo');
  },
  (error) => {
    assert(error.message === 'bar');
    return true; // requirement :(
  }
);
// AssertionError:   # test.js:8
//
//   assert(error.message === 'bar')
//          |     |       |
//          |     "foo"   false
//          Error{}

throwsの改善

このままでも読めなくは無いですが、このテストケースの行数をもう少し減らしたいので、ヘルパを作成します。

test.js
import assert from 'power-assert';

function throws(block) {
  let error = {};
  try {
    block();
  } catch (e) {
    error = e;
  }
  return error;
}

assert(throws(
  () => {throw new Error('foo');},
).message === 'bar');
//
// AssertionError:   # test.js:13
//
//   assert(throws(() => { throw new Error('foo'); }).message === 'bar')
//          |                                         |       |
//          Error{}                                   "foo"   false

また上記ヘルパは、例外が発生しなかったとき、以下のように出力を得ます。

test.js
// ...
assert(throws(
  () => {/* noop */},
).message === 'bar');
//
// AssertionError:   # test.js:13
//
//   assert(throws(() => {}).message === 'bar')
//          |                |       |
//          |                |       false
//          Object{}         undefined

Promiseのrejectedのテスト

Promiseがrejectされたテストを書きたいときも、単純に書くとやや助長です。

test.js
import Promise from 'bluebird';
import assert from 'power-assert';

Promise.resolve('foo').then(
  () => {
    throw new Error('Missing expected rejection..');
  },
  (reason) => {
    assert(reason.message === 'bar');
  }
);
// Unhandled rejection Error: Missing expected rejection..

Promise.reject(new Error('foo')).then(
  () => {
    throw new Error('Missing expected rejection..');
  },
  (reason) => {
    assert(reason.message === 'bar');
  }
);
//
// Unhandled rejection AssertionError:   # test.js:9
//
//   assert(reason.message === 'bar')
//          |      |       |
//          |      "foo"   false
//          Error{}

ビルドインのPromiseはthrowすると何も出力しないため、bluebirdを使用しています

babel-stage-1babel-polyfillasync/await文が使えるため、これもヘルパを利用して簡素に書くことが可能です。

test.js
import Promise from 'bluebird';
import assert from 'power-assert';

function rejects(promise) {
  return promise
  .then(
    () => Promise.reject(new Error('Missing expected rejection..')),
    (reason) => Promise.resolve(reason),
  );
}

async function test1() {
  assert((await rejects(Promise.resolve('foo'))).message === 'bar');
}
async function test2() {
  assert((await rejects(Promise.reject(new Error('foo')))).message === 'bar');
}

test1();
// Unhandled rejection Error: Missing expected rejection..

test2();
// Unhandled rejection AssertionError:   # test.js:14
//
//   assert((await rejects(Promise.reject(new Error('foo')))).message === 'bar')
//           |             |       |      |                   |       |
//           |             |       |      Error{}             "foo"   false
//           |             |       Promise{_bitField:16777216,"_fulfillmentHandler0":#Error#,"_rejectionHandler0":undefined,"_promise0":undefined,"_receiver0":undefined}
//           Error{}       #function#

assert-exception

上記ヘルパthrows, rejectsを、assert-exceptionという名前で公開しています。

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