C# テスト駆動開発の実践方法:オブジェクトを改修してテストする2 #10

当連載ではC#を使ったテスト駆動開発(TDD)を実践する方法について、基礎的な知識から実践的な内容を解説しています。過去のアーカイブについては「C# テスト駆動開発の実践方法」より確認してもらえればと思います。

さて、今回は前回の内容に引き続いて、作成してきたオブジェクトに新規機能を追加していきたいと思います。前回はMoneyクラスに足し算を行う機能として「Add」を作成しました。今回はその逆である引き算をするメソッドを追加していきます。

前回に引き続き、同じアプリケーションを開いて開発を進めていきたいと思います。まだまだオブジェクトの設計段階で簡単な内容ではありますが、テストファーストを実践して開発を進めていきましょう。

引き算のテストを作成する

それでは引き算に対応するメソッドを作成するために定義しておきたいテストから書いていきたいと思います。前回から引き続いて「UnitTest1.cs」にテストメソッドを追加しましょう。

[TestMethod]
public void SubtractMoneyTest()
{

}

まずは中身のない空のメソッドで問題ありません。”[ ]”で囲まれた属性はきちんと記述しているでしょうか?この属性がないとテストメソッドとしてみなされないので注意が必要になります。

では、引き算のための「失敗するテスト」を書いていきます。今回は引き算を「Subtract」メソッドにしたいと考えています。Moneyオブジェクトに対して引き算を行います。

[TestMethod]
public void SubtractMoneyTest()
{
    var money = new Money(100);
    var newMoney = money.Subtract(new Money(50)).Subtract(new Money(10));
    Assert.AreEqual(newMoney.Value, 40);
}

上記のように書けたら、いったんはOKとします。この時点では、まだSubtractメソッドは定義されていませんのでコンパイルエラーになるはずです。

メソッドを定義して失敗させる

さて、テストメソッドが記述できたらクラスにメソッドを定義していきます。今回はMoneyクラスにSubtractメソッドを作成していくのでした。Moneyクラスのインスタンスを返すので、戻り値と引数はともにMoneyクラスになりますね。

public object Subtract(Money money)
{
    throw new System.NotImplementedException();
}

「money.Subtract」のSubtract部分にカーソルを合わせながら、”ctrl”を押しながら”.”を押下すると上記のようなメソッドを自動生成してくれます。戻り値がobjectなので、これをMoneyに変更して、自動で生成されたメソッドでテストを通して期待通り「レッド」になるかを確認します。

System.NotImplementedException();

「System.NotImplementedException();」は自動生成してくれるメソッド等で必ず埋め込まれる例外ですので、期待通り「レッド」の状態になるはずです。

メソッドを修正して成功させる

ここからテストを「グリーン」にしていきましょう。前回と似たような感じになりますので、ここはサクッと終わらせたいと思います。あまり難しくないので、完成形だけ以下に書いておきたいと思います。

public Money Subtract(Money money)
{
    var newValue = this.Value - money.Value;
    return new Money(newValue);
}

こんな感じになったでしょうか。それではテストを実行して、先ほど「レッド」だった状態が「グリーン」に代わるかを確認します。テストを実行すると全テストが問題なくグリーンになるかと思います。これで引き算のメソッドの実装が完了したことになります。

失敗のテストも書いてみよう

さて、これまで「足し算」と「引き算」の機能を追加してきたわけですが、2つとも記述してきたテストは「正常パターン」のみでした。少し練習もかねて「失敗するテスト」も書いてみましょう。ここは練習問題として自分の力で書いてみてください。Assertクラスには様々なメソッドがありますが、今回はAreNotEqualメソッドを使用するとよいでしょう。

[TestMethod]
public void AddMoneyTest_NG()
{
    var money = new Money(100);
    var newMoney = money.Add(new Money(60));
    Assert.AreNotEqual(newMoney.Value, 150);
}

上記のようなメソッドと以下のようなメソッドが記述できたでしょうか。あまり意味のないテストではありますが、一応ちゃんと確認しておいても良いかと思います。「正しくないものは正しくない」のも重要な確認事項の一つですからね。

[TestMethod]
public void SubtractMoneyTest_OK()
{
    var money = new Money(100);
    var newMoney = money.Subtract(new Money(50));
    Assert.AreEqual(newMoney.Value, 60);
}

というわけで自力でこの2つのテストが書ければ一旦はOKとしておきましょう。少しづつテスト駆動開発のイメージがついてきたのではないでしょうか。今回の失敗を検証するテストメソッド名は最後に「_NG」としているので、区別するために成功を検証するメソッド名にも「_OK」を付けておきましょう。そしてテストを実行し、すべてがグリーンになっているかを確認して、今回の記事は終了にしたいと思います。