« [NEWS] Visual Studio と NUnit が統合される(続) ~ Unit Test Explorer の動画 | トップページ | [コラム] TDDBC 東京 1.6 のお題を C# でやってみる (その2) ~ 最初の仕様変更[T16MAIN-5] »

2011年8月 2日 (火)

[コラム] TDDBC 東京 1.6 のお題を C# でやってみる (その1)

2011/7/31 に、 3回目となる東京 TDDBC 「TDD Boot Camp 東京 1.6」 が開催されました。 当日の tweet は 「TDD Boot Camp 東京 1.6 #tddbc」 に纏められていますので、 参加できなかったかたはどうぞ。

かくいう私も参加できなかったわけですが、 午後に行われた実習の課題を C# でやってみたいと思います。 まず、 仕様変更が入る前まで。

提示された仕様は、 以下の T16MAIN-1 ~ T16MAIN-4 までです。

■ T16MAIN-1: put で key と value を追加し、 dump で一覧表示、 get で key に対応する value を取得できる
put で key と value を追加する
• dump で登録されている一覧を表示
• get で指定した key の value を取得
注1) key に null をわたすと例外が発生
注2) value の null は許容する

■ T16MAIN-2: delete で指定の key-value を削除
delete で指定した key と value を削除する
• 存在しない key が渡されたら何もしない
• null を渡すと例外が発生する

■ T16MAIN-3: put の引数に既に存在する key が指定された場合、 value のみを更新する
put で既に存在する key の場合は value を更新する

■ T16MAIN-4: key と value のセットを一度に複数追加できる
複数の key と value をまとめて追加できるようにする
同じキーが複数ある場合、一番最後に指定されたものが使用される。
既に存在するキーがある場合も、今回指定したものが優先される。
指定した引数の中に null のキーがある場合、例外を投げ、状態を元に戻す。

.NET Framework では、 ここまでは Dictionary<string, string> を使うとサックリできてしまいます。 ソースコードは GitHub に上げました。 ⇒ biac/tddbc-tokyo-1.6 (イニシャル コミット)
テストケースは、 上記の仕様の順に上から順番に書いてあります。 書いてみたけれど RED にならなかったテストケースは、 まだ消さずにコメントアウトしてあります。 また、 仕様が曖昧なところは、 TODO: として記録してあります。

テストケースのコードについて、 少々解説しておきます。

  • Put() だけでは Assert が書けないので、 いきなり Put() と Get() を合わせてテストケースを書きます。
  • 最初のテストケースで、 実装の呼び出し結果をわざわざ string result = dic.Get(key); と変数に受けているのは、 Git() メソッドのスケルトンを自動生成させるときにメソッドの型を正しく推定してもらうためです。
  • ひとつだけ Put() / Get() するテストケースが実現できると、 複数 Put() するテストケースを書いてみても RED にならないと分かります。 ので、 そのテストケースは書いていません。
  • Dump() のテストケースでは、 Put() した順序で出力されるべきでしょう。 そこで、 複数 (2個) Put() してから Dump() して Assert しています。 なお、 ここで 2回めの Put() の value に null を与えていますが、 この時点の実装では null で RED にならないので、 じつは null を与える必然性はありません。 安心を得るためだけに null をテストケースに含めました。
  • Dump() のテストケースの中で、 実際にコンソールへダンプ出力を出すためのサンプルコードを書いています。 (スローテストの原因になるようなら、 削除します。)
  • Delete() のテストケースでも、 ひとつ Put() して、 ひとつ Delete() するだけです。 その実装をした時点で、 複数やってみても RED にならないと分かるので、 それは書いていません。 また、 存在しない key や null で Delete() を呼び出したときは、 どうなるかよく分からなかったのでテストケースを書きましたが、 RED にならなかったのでコメントアウトしてしまいました。
  • 複数まとめて追加するためのメソッドは、 Put() をオーバーロードするという手もありますが、 メソッド名で識別できる方が好きなので、 MultiPut() メソッドを新設しました。 追加するデータの中に、 重複キーがある場合も含めて、 一度に実装しています。 (実装は、 foreach で回して、 自分自身の Put() メソッドを呼び出しているだけです。)
  • MultiPut() メソッドは、 受け取った複数のデータ中にひとつでも key が null のものがあった時に 「状態を元に戻す」 とされています。 しかし、 実際にロールバックしようとすると大変なので、 事前に null チェックを実装することにしました。

こうして出来上がったテストケースは 199行 (空行除いて 154行)、 製品コードは 37行  (空行除いて 29行) となりました。 前述したように Dictionary<string, string> クラスを使っているため、 とてもコンパクトに実装出来ています。
※ この時点でのソースコード一式 ⇒ tddbctokyo1.6_C#01.zip (9KB)  (C# 2010 + NUnit 2.6)

以下に、製品コードを載せておきます。

using System;
using System.Collections.Generic;
using System.Linq;

namespace TddbcTokyo16 {
  public class TddbcDictionary {

    private Dictionary<string, string> _dic = new Dictionary<string, string>();

    public void Put(string key, string value) {
      this._dic[key] = value;
    }

    public string Get(string key) {
      return this._dic[key];
    }

    public IList<KeyValuePair<string, string>> Dump() {
      return this._dic.ToList<KeyValuePair<string, string>>();
    }

    public void Delete(string key) {
      this._dic.Remove(key);
    }

    public void MultiPut(IList<KeyValuePair<string, string>> data) {
      foreach (var kv in data) {
        if (kv.Key == null)
          throw new ArgumentNullException();
      }
      foreach (var kv in data) {
        this.Put(kv.Key, kv.Value);
      }
    }
  }
}


さてこの後、 仕様変更の嵐に翻弄されると、 どうなるのでしょう… (続く)

|

« [NEWS] Visual Studio と NUnit が統合される(続) ~ Unit Test Explorer の動画 | トップページ | [コラム] TDDBC 東京 1.6 のお題を C# でやってみる (その2) ~ 最初の仕様変更[T16MAIN-5] »

*コラム」カテゴリの記事

<NUnit>」カテゴリの記事

コメント

コメントを書く



(ウェブ上には掲載しません)


コメントは記事投稿者が公開するまで表示されません。



トラックバック


この記事へのトラックバック一覧です: [コラム] TDDBC 東京 1.6 のお題を C# でやってみる (その1):

» [コラム] TDDBC 東京 1.6 のお題を C# でやってみる (その2) ~ 最初の仕様変更[T16MAIN-5] [TDD.NET]
前回の記事で、 当初の仕様 (T16MAIN-1 ~ 4) を満たすコードは、 さっくり完成しました。 というところで… TDDBC 名物、 仕様変更がやってまいりました!■ T16MAIN-5: put の引数で key, value, date(時刻情報) を渡し、 dump を時間順に出力するように仕様変更・ p... [続きを読む]

受信: 2011年8月18日 (木) 16時38分

« [NEWS] Visual Studio と NUnit が統合される(続) ~ Unit Test Explorer の動画 | トップページ | [コラム] TDDBC 東京 1.6 のお題を C# でやってみる (その2) ~ 最初の仕様変更[T16MAIN-5] »