Nodejsで非同期のユニットテストコードを作成します.

3606 ワード

Nodejsの開発過程において、非同期という話題はどうしても避けられないものであり、非同期に関する文章はすでに何編もありました.私もウェブアプリケーションを開発する過程で、Nodejsにおいて、どのように非同期コードを処理するべきかを書くつもりはありません.先日、私はユニットのカバー率をテストするという指标にサインしました.Nodejsのプロジェクトを书いていますので、このプロジェクトのテストコードの量があまり少なくないように望んでいます.目的は100%のラインカバー率です.ですから、最近多くのユニットのテストコードを书きました.使っているテストフレームはMochaで、ライブラリはChaiと言い切っています.じゃ、今日はユニットテストにおいて、非同期コードを処理する姿勢についてお話します.
プロミスを処理する
const { query } = require('../app/utils/async-db');
const { should } = require('chai');
const mysql = require('mysql');
should();

/**
 *             
 */
describe('mysql connect success state', function() {
  it('should return an array', function(done) {
    let sql = 'SELECT * FROM `Users`';
    query(sql)
      .then((rows) => {
        rows.should.be.an('array');
        done();
      })
      .catch(err => {
        done(err);
        throw err;
      });
  });
});


まず、今日の例を見てみますと、このコードはデータベース接続状態をテストするライブラリです.断言ライブラリの中で、私はショルダータイプを使用する傾向があります.もっと意味化しているので、TDDの読書習慣に合っています.このコードは問題ないようですが、運行したらエラーが発生します.
Error: Timeout of 2000ms exceeded. For async tests and hooks, ensure "done()" is called; if returning a Promise, ensure it resolves.
なぜですか?原因は2行目、4行目です.
const { should } = require('chai');
...
should();

このようにショルダーを引用した後、先ほどのコードのようにショルダーは使えません.なぜ私はこのような文法を書きましたか?私は当時怠けて適当にブログを見たら猫の絵を描きました.今後は必ず公式文書に従ってきます.ここでまず誤りを訂正します.正しいコードは以下の通りです.
const { query } = require('../app/utils/async-db');
const should = require('chai').should();
const mysql = require('mysql');

/**
 *             
 */
describe('mysql connect success state', function() {
  it('should return an array did not have done', function(done) {
    let sql = 'SELECT * FROM `Users`';
    query(sql)
      .then((rows) => {
        rows.should.be.an('array');
        done();
      })
      .catch(err => {
        done(err);
        // throw err;
      });
  });
});
このようにpromiseでは、thenに直接に断言を書き、その後doneについて、テストが完了すれば、非同期テストを成功させることができます.
直接プロに戻る方法もあります.
/**
 *             
 */
describe('mysql connect success state', function() {
  it('should return an array did not have done', function() {
    let sql = 'SELECT * FROM `Users`';
    return query(sql)
      .then((rows) => {
        rows.should.be.an('array');
      });
  });
});

書き方の違いを直接言ってください.2行目のコードのitブロックに、コールバックのfunctionにはdoneコールバックを入れないでください.そうでないとテストプログラムはずっとあなたのdoneコールバックを待っています.タイムアウト後にエラーが発生します.doneフィードバックを除いたら、直接に結果を書けばいいです.もしcatchがerrorに来たら、直接に投げられてテストに失敗します.
この2つの方法は書き終わって、このように書くのがとてもくどいと感じる多くの学友がいるべきでしょう.じゃ私達は一つのchaiが倉庫の中間部品を言い切ることを見にきて、この中間部品はpromise関連の断言を大いに簡略化することができます.この倉庫はchai-as-promisedです.このライブラリの中で最も重要なAppを提供しているのはshould.eventuallyです.直接に文字どおりにこのチェーンを理解してください.promiseの最終的な実行結果を待ってテストして断言します.まだ先の例です.このプラグインで書き換えたらこうなります.
const { query } = require('../app/utils/async-db');
const chai = require('chai');
const chaiAsPromised = require('chai-as-promised');
chai.use(chaiAsPromised);
chai.should();

/**
 * chai-as-promised      
 */
describe('Mysql connect', function() {
  //     chai-as-promised       function    done   
  it('should return an array', function() {
    let sql = 'SELECT * FROM `Users`';
    return query(sql).should.eventually.be.an('array');
  });
});

瞬間テストのコードブロックの中には二行しかコードが残っていません.見ていて特にさわやかですか?このような使い方を少し勉強して、異歩のユニットテストを信じて、これからはクラスメートにとっておかずになります.