2016-06-28 9 views
0

私はASP.NET MVCプロジェクトを開発しています。私のプロジェクトでは、単体テストをやっています。私はユニットテストのためにMoqを使用します。しかし、私はモデルクラスのメソッドのテストに問題を抱えています。これはそのクラスの別の関数に依存しています。下記の私のシナリオをご覧ください。ASP.NET MVCユニットテストでMoqを使用してテストクラス自体の機能を模擬する方法

これは私がGenerateItemCode方法に

[TestClass] 
    public class ItemRepoTests 
    { 
     [TestMethod] 
     public void GenerateItemCode_IncreaseDigit() 
     { 
      Item[] items = new Item[]{ 
       new Item{ 
        ItemCode = "DN999934" 
       } 
      }; 
      ItemRepo itemRepo = new ItemRepo(); 
      //I want to mock GetItems method here 
     } 
    } 

をテストしたい私は

public class ItemRepo:IItemRepo 
{ 
    private DbContext context = new DbContext(); 

    public IEnumerable<Item> GetItems() 
    { 
     return context.items; 
    } 

    public string GenerateItemCode() 
    { 
     Item item = this.GetItems.OrderByDescending(x=>x.Id).FirstOrDefault(); 
     //do something 
     return itemCode; 
    } 
} 

をテストしたいモデルクラスのサンプルである私は、私がテストコードでモックとしたいものをコメントしています。どのように私はその方法を模擬することができますか?どのように私は、そのメソッドのモック依存関係関数をテストすることができますか?

+0

'items'はどのようにモデルに導入されますか? 。それは内部で作成されるか、クラスに注入されますか? – Nkosi

+0

この質問のGetItemsメソッドのコードはかなり重要です。データベースからデータを取得する方法を示すように、追加してください。たとえば、EF DbContextを使用している場合、単体テストを実行するための模擬DbContextを注入することをお勧めします。 – uk2k05

+0

GetItemsメソッドは返されるcontext.Items –

答えて

2

を記述するために、testetありませんコンテキストクラスから項目を取得しているというあなたのコメントは、これはあなたがMockingする必要があるクラスです。

その周りの多くの記事があります。だから、基本的に、あなたはあなたのユニットテストでモックDbContextを作成し、偽のリストを渡しHow to mock DbContext and DbSet with Moq for unit testing?

[TestClass] 
public class ItemRepoTests 
{ 
    [TestMethod] 
    public void GenerateItemCode_IncreaseDigit() 
    { 
     Item[] items = new Item[]{ 
       new Item{ 
          ItemCode = "DN999934" 
         } 
     }; 

     var mockContext = new Mock<YourContext>(); 
     // Code to inject items into mock context 

     // You may have to implement the context injection into your ItemRepo 
     // class if you do not already have it 

     ItemRepo itemRepo = new ItemRepo(mockContext.Object); 

     var result = itemRepo.GenerateItemCode(); 

     // Code to check result is correct 
    } 
} 

Google検索でDbContext、トップの結果を模擬する方法を説明したり、そのようなアイテムデータを含む。テストしているクラスにこのモックを注入し、テストを実行します。コードがうまくいっていれば、正しい結果が相手に吐き出されます。

+0

前のコメントを削除しました。問題はそれがIDBSetを模倣することです。しかし、私のコンテキストはDbSetを使用しています。私はDbSetと嘲笑することはできません。だから、エンティティのための私のコンテキストクラス内のすべてのIDbSetを変更しました。しかし、私がIDbSetに変更すると、ItemでremoveRangeを使う関数があります。だから私はIDbSetにremoveRangeを使うことはできません。だから、どんな考えですか? –

+0

パフォーマンスを向上させるためにremoveRangeを使用しています。 –

0

デリゲートでのgetItemsを置き換える:テストコードで

public class ItemRepo : IItemRepo 
{ 
    public Func<System.Collections.Generic.IEnumerable<Item>> Items =() => 
     { // all your orignal code 
      return items; 
     }; 

     public string GenerateItemCode() 
     { 
     Item item = Items().OrderByDescending(x => x.Id).FirstOrDefault(); 
     //do something 
     return itemCode; 
     } 
} 

をデリゲートを置き換える:

public class ItemRepoTests 
{ 
    [TestMethod] 
    public void GenerateItemCode_IncreaseDigit() 
    { 
     Item[] items = new Item[]{ 
      new Item{ 
       ItemCode = "DN999934" 
      } 
     }; 
     ItemRepo itemRepo = new ItemRepo(); 
     itemRepo.Items =() => items; 
     //I want to mock GetItems method here 

     itemRepo.GenerateItemCode() 
    } 
    } 

擬似コードをのみあなたが言及したアイデア

+0

完全なコードを取得できますか?私ははっきりしていません。 –

+0

デリゲートを使用すると、デリゲート関数内のテスト済みクラスの他のプロパティにアクセスできません。 –

関連する問題