2016-03-30 10 views
1

私はEFでGenericRepositoryを作成して初めてユニットテストを作成しています。 GetAll()およびUpdate()のテストが合格したが、Add()およびDelete()に合格しなかった。なぜそれがAddではないのですか?私はそれが1行のコードであり、私はそれを理解することができなかったので、私の髪を引っ張っています。私はEFデータベースを使用しています。まず、Nunit、Nsubstitute。テスト時に汎用リポジトリがコンテキストにエンティティを追加しない

アドバイスは歓迎されます。

​​

MyEntities

public partial class MyEntities : DbContext{ 
public MyEntities() 
    : base("name=MyEntities") 
{ 
} 

protected override void OnModelCreating(DbModelBuilder modelBuilder) 
{ 
    throw new UnintentionalCodeFirstException(); 
} 

public virtual DbSet<Customer> Cusotmers{ get; set; } 

テスト

public static class NSubstituteUtils { 
    public static DbSet<T> CreateMockDbSet<T>(IQueryable<T> data = null) 
     where T : class { 
     var mockSet = Substitute.For<DbSet<T>, IQueryable<T>>(); 
     mockSet.AsNoTracking().Returns(mockSet); 

     if (data != null) { 
      var queryable = data.AsQueryable(); 

      // setup all IQueryable methods using what you have from "data" 
      ((IQueryable<T>)mockSet).Provider.Returns(data.Provider); 
      ((IQueryable<T>)mockSet).Expression.Returns(data.Expression); 
      ((IQueryable<T>)mockSet).ElementType.Returns(data.ElementType); 
      ((IQueryable<T>)mockSet).GetEnumerator().Returns(data.GetEnumerator()); 
     } 

     return mockSet; 
    } 
} 

static IQueryable<Customer> data; 
[SetUp] 
    public void Init() { 
     data = new List<Customer> { 
      new Customer { 
       CUSTOMER = "333", 
       CUSTOMERNAME = "no name" 
      }, 
      new Customer { 
       CUSTOMER = "555", 
       CUSTOMERNAME = "test name" 
      } 
     }.AsQueryable(); 
    } 
[Test] 
    public void Add_Should_AddGenericT() { 

     var mockSet = NSubstituteUtils.CreateMockDbSet<Customer>(data); 
     var mockContext = Substitute.For<MyEntities>(); 
     mockContext.Set<Customer>().Returns(mockSet); 

     var repo = new GenericDataRepository<Customer, MyEntities>(mockContext); 

     var customer = new Customer { 
      CUSTOMER1 = "123", 
      CUSTOMERNAME = "test name" 
     }; 
     var result = repo.Add(customer);  // issue here: result returns null which should be a Customer 
     repo.Save(); 

     var customerList = repo.GetAll().ToList(); 
     Assert.AreEqual(3, customerList.Count); // failed. Expected 3 but was 2 
    } 
+0

あなたの 'Customer'タイプは、対応するエンティティタイプと一致しますか? –

+0

私は 'Customer'のすべてのプロパティを含んでいませんでした。フィールドの一部はnullにできません。しかし、 'repo.Save()'は例外をスローしませんでした。 – Firefly

+0

申し訳ありませんが、明確にするために、 'Customer'タイプは、エンティティフレームワークのテーブルにマップされているものと同じタイプでなければなりません。あなたのコンテキストをどのようにマップしましたか? Database-FirstまたはCode-Firstを使用していますか? –

答えて

0

あなたはすぐにここでのIQueryableなどのデータ変数を定義し、あなたのリポジトリに_dbSetをモックするためにそれを使用しています。

data = new List<Customer> { 
     new Customer { 
      CUSTOMER = "333", 
      CUSTOMERNAME = "no name" 
     }, 
     new Customer { 
      CUSTOMER = "555", 
      CUSTOMERNAME = "test name" 
     } 
    }.AsQueryable(); 

あなたが実際に読み取り専用のインタフェースであるのIQueryableに追加しているので、あなたが.Addを(やっているとき)。

データ定義からAsQueryable()を削除し、実際のリストを使用します。

+0

それは問題と思われる。 'mockSet'は' IQueryable 'として返します。しかし、私はDbsetを模倣するために 'IQueryable'が必要です。 'mockSet'をリストとして返す方法を知りましたか? – Firefly

+0

私はNS substituteに精通していませんが、単体テストにMoqを使用するときにIDbSetを処理するために 'Add()'と 'Remove()'メソッドの両方を実装する必要がありました。 2つの.Setup()メソッドを見てください:[link](https://dotnetfiddle.net/6IJHty) あなたのモックフレームワークで同じことをしなければならないかもしれません。 –

関連する問題