2017-08-03 11 views
0

ユニットテストを既存のコードベースに追加しようとしていますが、サイトの構築方法によって最初のハードルがかなり下がります。ユニットテスト - 静的クラスへの呼び出しをリファクタリングする方法

このサイトのすべてのコントローラは、SiteControllerというベースコントローラから継承し、そのコントローラのコンストラクタは静的ヘルパークラスを使用してデータを取り込みます。例えば

public class HomeController : SiteController 
    { 
     public ActionResult Index() 
     { 
      //Do stuff here 
     }  
    } 

そして、ここでは、ベースコントローラ

public class SiteController 
{ 
    public SiteController() 
    { 
     viewModel = CategoryHelper.GetAllCategories(); 
    } 
} 

と静的GetAllCategoriesヘルパーメソッド

public static class CategoryHelper 
    { 
     public static IList<string> GetAllCategories() 
     { 
      //Go off and get the categories from the WCF layer 
      return _categories; 
     } 
    } 

私は静的クラスをモックすることはできませんが、どのように私ができるのですこのコードをリファクタリングして、単体テストを使って作業することができます。私たちはすでにサイト全体でDIを使用しています。私はこの静的クラスを、一般的にはコードにとってより良い抽象化レイヤーにラップする必要があるということをここでは知っています。しかし、これの実用性について私はあまり確信していません。

おそらく明らかですが、ここで私の目的はサイトを(明らかに)動作させ、静的なクラスやその呼び出しを単体テストで書き直すことです。私は単体テストを書くのが初めてなので、これらの問題にぶつかり、テストに合格するためには1つのグリーンティックを見ても満足しています!私は理論的な解決策を知っていますが、問題のクラスに実際に何をしてそれを働かせるか分からないとき、それはイライラしています。

+0

あなたは確信しているビットについてもう少し具体的にできますか?あなたは何をする必要があるかをほとんど正確に記述していますので、何があなたを上回っているかはわかりません。 –

+1

またはラッパーを使用する代わりに静的クラスを使用して*停止する* – BradleyDotNET

+0

実際の問題は何ですか? 「これを単体テストでどのように使うことができますか?」は、初心者ではありません。あなたはそれを使って、それを使っています。 '静的'は理想的には避けなければならないことが多く、過度に使用されたり誤使用されることはよくありますが、本質的に間違っているわけではありません。あなたが直面している*実際の問題は何ですか? – David

答えて

2
public class HomeController : SiteController 
{ 
    public HomeController(ICategoryHelper categoryHelper) : base(categoryHelper) 
    { 
    } 

    public ActionResult Index() 
    { 
     //Do stuff here 
    }  
} 

public class SiteController 
{ 
    public SiteController(ICategoryHelper categoryHelper) 
    { 
     viewModel = categoryHelper.GetAllCategories(); 
    } 
} 

public class CategoryHelper : ICategoryHelper 
{ 
    public IList<string> GetAllCategories() 
    { 
     //Go off and get the categories from the WCF layer 
     return _categories; 
    } 
} 

public interface ICategoryHelper 
{ 
    IList<string> GetAllCategories(); 
} 

最も重要なことは、具体的なクラスではなく、抽象化に対してコード化することです。 CategoryHelperは具体的なクラスです。コントローラーに、その作業の仕方を気にせずに作業を実行するものを使用したいとします。したがって、コントローラーはコンストラクターでインターフェースを受け入れる必要があります(必要に応じてベースコントローラーに渡すこともできます)。

同様に、CategoryHelperはインターフェイスを実装する必要があります。これは基本的には「私はICategoryHelperの作業を実行できます」という契約です。

次に、依存性インジェクタのICategoryHelper依存性を満たすためにCategoryHelperを接続します。どのように行うかは、使用する特定のツール(AutoFac、Ninject、SimpleInjectorなど)によって異なります。

注:カテゴリが頻繁に変更されない場合は、キャッシングパターンがより良い場合があります。

関連する問題