2018年01月19日

Mochaを使ったユニットテストベースのコーディングっていいよね、を伝えたいメモ

概要

Mochaを使ったユニットテストベースのコーディングっていいよね。何が「良い♪」って、「テストで仕様を定めて(設計して)、その後に実装する」ってのが良いよねー。期待した設計に成っているか、を勝手に検証してくれらから♪

・・・を伝えたいんだけど、どう伝えたらよいか分からない。たとえば、こんな流れが「良い♪」って思うんだよ、のメモです。

テストで設計して、実装する流れ。

こんな設計!をテストで書く。

return shouldFulfilled(
    api_vi_activitylog_remove( queryFromGet, dataFromPost )
).then(function( result ){
    
    assert( stubs.sql_parts.createPromiseForSqlConnection.calledOnce, "createPromiseForSqlConnection()が1度呼ばれる" );
    assert( stubs.sql_parts.closeConnection.calledOnce );
    assert( stubs.sql_parts.isOwnerValid.calledOnce );
    // ここまでは、API_V1_BASE()で検証済みなので、簡易検証。

    // isOwnerValid()へ渡されるパラメータを直に検証する。
    // 何故なら「get〜()で生成したオブジェクトを直に渡す」ではなく、このテスト対象の中で生成するから。
    expect( stubs.sql_parts.isOwnerValid.getCall(0).args[0] ).to.equal( TEST_CONFIG_SQL.database );
    expect( stubs.sql_parts.isOwnerValid.getCall(0).args[1] ).to.equal( dataFromPost.device_key );
    expect( stubs.sql_parts.isOwnerValid.getCall(0).args[2] ).to.equal( dataFromPost.pass_key );
    
    var deletedResponse = stubs.sql_parts.deleteActivityLogWhereDeviceKey;
    assert( deletedResponse.calledOnce, "SQLへのログ削除クエリー。deleteActivityLogWhereDeviceKey()が1度呼ばれること。" );
    expect( deletedResponse.getCall(0).args[0] ).to.equal( TEST_CONFIG_SQL.database );
    expect( deletedResponse.getCall(0).args[1] ).to.equal( dataFromPost.device_key );
    expect( deletedResponse.getCall(0).args[2] ).to.be.null; // { start, end } を指定しない。⇒全期間が対象になる。

    assert( stubs.sql_parts.getNumberOfLogs.calledOnce, "getNumberOfLogs()が1度だけ呼ばれること。" );
    expect( stubs.sql_parts.getNumberOfLogs.getCall(0).args[0] ).to.equal( TEST_CONFIG_SQL.database );
    expect( stubs.sql_parts.getNumberOfLogs.getCall(0).args[1] ).to.equal( dataFromPost.device_key );

    assert( stubs.sql_parts.deleteExistUser.calledOnce, "deleteExistUser()が1度だけ呼ばれること。" );
    expect( stubs.sql_parts.deleteExistUser.getCall(0).args[0] ).to.equal( TEST_CONFIG_SQL.database );
    expect( stubs.sql_parts.deleteExistUser.getCall(0).args[1] ).to.equal( dataFromPost.device_key );

    expect( result ).to.be.exist;
    expect( result ).to.have.property("status").to.equal(200);
    expect( result ).to.have.property("jsonData");
    expect( result.jsonData ).to.have.property( "removed" );
    expect( result.jsonData.removed ).to.deep.equal({
        "device_key" : dataFromPost.device_key
    });
});

以下実装していく様子

先ずは、枠だけ作ったヤツを実行。当然失敗する。

01.枠だけ.png

設計であるテストコードを見てみる。

02.テストが設計そのもの.png

失敗したテストに応じて実装していく。

03.実装していく.png 04.実装していく.png 05.実装していく.png 06.実装していく.png 07.実装していく.png 08.実装していく.png 09.実装していく.png 10.実装していく.png 11.実装していく.png

実装ミス(今回のはtypo)は、テストの失敗として検出できる。

12.実装したはずなのに失敗した.png 13.ここが間違ってる.png

完成

無事に全部テストがpassした=実装が完了!

14.全部パス.png

・・・っての、伝えたいし、以前に知りたかったのだが、、、どう伝えたら良いか分からない、見たことが無い。

参考サイト

posted by ほしまど at 23:15| Comment(0) | メモ書き
この記事へのコメント
コメントを書く
お名前:

メールアドレス:

ホームページアドレス:

コメント: