web-dev-qa-db-ja.com

TDDのヘルパー静的メソッド

テスト可能なアプリケーション(ユニット+統合)を作成しています。このアプリケーションには、FileHelper静的クラスがあります。

public static class FileHelper
{
    public static void ExtractZipFile(Stream zipStream, string location)
    {
        ..................................
    } 
    public static void CreatePageFolderIfNotExist(string directory)
    {
        .................................................
    }

    .......................................................
    .......................................................
}

しかし、静的なため、テストできないと思います。このクラスをテスト可能にする方法は?

7
user960567

テストできないと言うのは不正確です。これらは非常にテスト可能ですが、モック可能ではないため、テストに適していません。つまり、このメソッドを呼び出すコードのユニットをテストするたびに、メソッドをテストする必要があります。メソッドが壊れた場合、多くのテストが失敗し、その理由は明らかではありません。

それを念頭に置いて、解決策はかなり明白です。それを非静的クラスにして、すべてのメソッドを持つインターフェースを抽出し、ヘルパーを必要なすべてのクラスに、できればコンストラクターを介して、できればIOC Containerを使用して)渡します。

public class FileHelper : IFileHelper
{
    public void ExtractZipFile(Stream zipStream, string location)
    {
        ..................................
    }

    public void CreatePageFolderIfNotExist(string directory)
    {
        .................................................
    }

    .......................................................
    .......................................................
}

public interface IFileHelper
{
    void ExtractZipFile(Stream zipStream, string location);
    void CreatePageFolderIfNotExist(string directory);

    .......................................................
    .......................................................
}

public class MyClass
{
     private readonly IFileHelper _fileHelper;

     public MyClass(IFileHelper fileHelper)
     {
         _fileHelper = fileHelper;
     }
}
9
pdr

Pdrの解決策の代わりに、静的関数をデリゲートとして使用するクラスに渡すことができます。これにより、モックアウトすることができますが、ボイラープレートコードの量がわずかに減少します

//warning! code not tested
static public class FileHelper 
{
    public static void ExtractZipFile(Stream zipStream, string location)
    {
         //do stuff
    }
}

public class MyClass 
{
    public Action<Stream, string> ExtractZipFile = FileHelper.ExtractZipFile
    public void DoThing()
    {
         //stuff
         ExtractZipFile(mystream, mystring);
         //more stuff
     }
}

MyClassTest()
{
     var target = new MyClass()
     target.ExtractZipFile = (stream, loc) => MaybeVerifSomething(loc);
     target.DoThing();
     //Assert stuff
}
1
jk.