C# テスト駆動開発の実践方法:データの書込機能を実装する #13

当連載ではテスト駆動開発を実践するために必要な基礎知識や実践方法を解説しています。現在は実践編として簡単なアプリケーションを作成しながらテスト駆動開発のやり方を解説しています。

過去の記事については「C# テスト駆動開発の実践方法」から確認できますので、テスト駆動開発について詳しく知りたい人は参考にしてみてください。さて、今回はよりアプリケーションに近づくためにデータの書込機能を実装していきます。

基本的には前回と同様の流れになりますが、BankRepository.csなどを作成する必要がない分、今回はコーディングのみで作業は完結することになるで、引き続きテストファーストで実施していきます。

テストをコーディングする

書込機能を作るので、早速、書込処理用のテストメソッドを記述していきましょう。基本的には読込機能に近いテストになるのですが、今回は書き出し処理を行った後、新ためてファイルを読み込んで値を確認するという手順を取ります。

[TestMethod]
public void WriteTest_OK()
{
    string path = @"C:\temp\balance.txt";
    var repos = new BankRepository(path);
    var money = new Money(10000);
    repos.Write(money);

    var balance = repos.Read();
    Assert.AreEqual(money.Value, balance.Value);
}

上記のようなテストメソッドを記載しました。最初の4行では値を書き込む処理を記載し、後の2行で正しく書き込めたかをチェックしています。現時点ではWriteメソッドの部分に赤線が引かれており、コンパイルエラーになっているので、次はコンパイルエラーを解消していきましょう。

コンパイルエラーを解消する

前までの状態ではBankRepository.csにWriteメソッドがないためコンパイルエラーとなっていました。コンパイルエラーを解消するために、BankRepositoryクラスにWriteメソッドを、以下のように実装します。

public void Write(Money money)
{

}

Writeメソッドはvoid型にするので、中身はない状態でもコンパイルは通るようになります。この状態でいったんテストを実施して「レッド」になることを確認しましょう。

レッドをグリーンにする

「レッド」の状態になる実装を加えて、問題なく「レッド」になることを確認したら、次は「グリーン」になるために実装を加えていきます。Writeメソッドに対して以下の修正をコーディングしてみましょう。

public void Write(Money money)
{
    if (!CanWriteFile()) { return; }
    var txt = (money.Value).ToString();
    WriteToFile(txt);
}

private bool CanWriteFile()
{
    var directory = GetParent();
    if (!IsExistDirectory(directory))
    {
        CreateDirectory(directory);
    }
    return true;
}

private void CreateDirectory(string path)
{
    Directory.CreateDirectory(path);
}

private bool IsExistDirectory(string path)
{
    return Directory.Exists(path);
}

private string GetParent()
{
    return Directory.GetParent(_path).FullName;
}

private void WriteToFile(string txt)
{
    File.WriteAllText(_path, txt);
}

記述するために必要な処理を諸々と入れ込みました。例えばディレクトリの存在判定、パスの親を取得する処理、ディレクトリの作成処理等々ですね。これらを入れこんでWriteメソッドが書き上げられればOKとします。

上記の状態までコーディングが完了したらテストを実施してOKになるかを確認しておきましょう。ReadのテストとWriteのテストでファイル操作を行っているで、ディレクトリを削除した状態でテストを実施すると「レッド」になる可能性もありますが2回目で問題なくなるはずですので、いったんはOKとしたいと思います。

次回はもうちょっと抽象化させたい

以上、ここまでに読込機能と書込機能を作成してきました。ここまでくれば概ね完成で、やりたいことはできていると思っています。しかし、もう少し捻りを加えてこれを具象の世界から抽象の世界で扱えるようにしたいと思います。

今現在はテキストという簡単な仕様なのであまり難しく感じることはないと思いますが、もし将来的に機能を拡張することが決まりDBを使用する、みたいな場面があるかもしれません。そういうときのために抽象化できるような準備を次回の記事では行いたいと思います。