2016-11-15 59 views
3

我想單元測試的DbContext從繼承IdentityDbContext起訂量:屬性設置正確,虛擬,但仍然有一個非虛成員無效設置

我正在與一個NotSupportedException錯誤信息很普通的消息:

System.NotSupportedException:在非虛擬無效的設置(在VB中重寫)成員

爲了找到一些線索,我已經重新添加一堆帖子。下面是一些示例:

顯然,溶液似乎設置dbSet作爲虛擬。我所做的。

運氣不好,錯誤依然存在。

這裏是我的IdentityDataContext

public class IdentityDataContext : IdentityDbContext<ApplicationUser> 
{  
    public virtual DbSet<Search> Searches { get; set; } 

    public IdentityDataContext() 
     : base("LocalDb", 
       throwIfV1Schema: true) 
    {    
    } 

    public static IdentityDataContext Create() 
    { 
     return new IdentityDataContext(); 
    } 
} 

這裏是我的搜索 POCO:

public class Search : BaseEntity 
{ 
    //BaseEntity is just an abstract class with createdAt,Id,updatedAt property 
    public string ConsumerIdentifier { get; set; } 
    public string LanguageCode { get; set; }   
} 

最後,這裏是我設置方法

[TestInitialize] 
public void SetupTest() 
{ 
    //DataInitializer.GetAllSearches() returns a List of "Search" 

    _searches = DataInitializer.GetAllSearches(); 

    var dbSet = new Mock<DbSet<Search>>(); 
    dbSet.As<IQueryable<Search>>().Setup(m => m.Provider).Returns(_searches.AsQueryable().Provider); 
    dbSet.As<IQueryable<Search>>().Setup(m => m.Expression).Returns(_searches.AsQueryable().Expression); 
    dbSet.As<IQueryable<Search>>().Setup(m => m.ElementType).Returns(_searches.AsQueryable().ElementType); 
    dbSet.As<IQueryable<Search>>().Setup(m => m.GetEnumerator()).Returns(_searches.AsQueryable().GetEnumerator()); 
    dbSet.Setup(d => d.Add(It.IsAny<Search>())).Callback<Search>(_searches.Add); 

    _dataContextMock = new Mock<IdentityDataContext>() 
    { 
     CallBase = true 
    }; 

    // The error appears here ---------------- _ 
    dataContextMock.Setup(x => x.Searches).Returns(dbSet.Object); 
    //---------------------------------------------------------------------- 

    _dataContextMock.Setup(x => x.Set<Search>()).Returns(dbSet.Object); 

    _searchRepository = new SearchRepository(_dataContextMock.Object); 
} 

我錯過了什麼?

回答

0

1)不需要單元測試DbContext。微軟已經做了大量的測試。

2)如果是的DbContext被用作另一個類的依賴則抽象的DbContext

public interface IDataContext { 
    DbSet<Search> Searches { get; set; } 
} 

public class IdentityDataContext : IdentityDbContext<ApplicationUser>, IDataContext { ... } 

public class SearchRepository { 
    public SearchRepository(IDataContext context) { ... } 
} 

不要依賴於結核,而是對抽象你們不類。 IdentityDataContext是依賴類不需要知道的實現細節。然後

這將允許測試

Mock<IDataContext> _dataContextMock; 

[TestInitialize] 
public void SetupTest() { 

    //DataInitializer.GetAllSearches() returns a List of "Search" 
    _searches = DataInitializer.GetAllSearches(); 
    var queryable = _searches.AsQueryable(); 

    var dbSet = new Mock<DbSet<Search>>(); 
    dbSet.As<IQueryable<Search>>().Setup(m => m.Provider).Returns(queryable.Provider); 
    dbSet.As<IQueryable<Search>>().Setup(m => m.Expression).Returns(queryable.Expression); 
    dbSet.As<IQueryable<Search>>().Setup(m => m.ElementType).Returns(queryable.ElementType); 
    dbSet.As<IQueryable<Search>>().Setup(m => m.GetEnumerator()).Returns(() => queryable.GetEnumerator()); 
    dbSet.Setup(d => d.Add(It.IsAny<Search>())).Callback<Search>(_searches.Add); 


    _dataContextMock = new Mock<IDataContext>(); 

    _dataContextMock.Setup(x => x.Searches).Returns(dbSet.Object); 

    _dataContextMock.Setup(x => x.Set<Search>()).Returns(dbSet.Object); 

    _searchRepository = new SearchRepository(_dataContextMock.Object); 

} 
+0

感謝這個更大的靈活性。這是我沒有想過的方法。 我在MSDN上閱讀了這篇文章(https://msdn.microsoft.com/en-us/library/dn314429(v = vs.113).aspx#Anchor_7)。我想知道爲什麼這種方法在我的情況下無法工作? 基本上,他們在實施存儲庫和工作單元設計模式時使用服務。但是那些目標相同:管理模型。我錯了嗎 ? – BertrandD