2016-11-15 4 views
3

würde ich ein DbContext zu Unit-Test wie die von erbt IdentityDbContextMoQ: Eigenschaft korrekt als virtuelle gesetzt, aber immer noch ungültiges Setup auf einem nicht-virtuelles Mitglied

Ich erhalte eine Fehlermeldung NotSupportedException mit der sehr häufig Nachricht:

System.NotSupportedException: Ungültige Setup auf einem nicht-virtuellen (overridable in VB) Mitglied

einige Hinweise finden ich schon wieder eine Reihe von Posts anzeigen. Hier sind einige Beispiele:

Offensichtlich ist die Lösung erscheint die dbSet als virtuelle gesetzt. Was ich getan habe.

Pech, der Fehler bleibt.

Hier ist meine 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(); 
    } 
} 

Hier ist meine Suche 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; }   
} 

hier Schließlich ist mein Set Up-Methode:

[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); 
} 

Was fehlt mir?

Antwort

0

1) keine Notwendigkeit, Unit Test DbContext. Microsoft hätte es bereits ausführlich getestet.

2), wenn die DbContext als eine Abhängigkeit für eine andere Klasse verwendet werden soll, dann abstrakt die DbContext

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

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

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

Haben Sie Klassen nicht concretions je nach, sondern auf Abstraktionen. IdentityDataContext ist ein Implementierungsdetail, über das abhängige Klassen nicht wissen müssen.

Dies würde dann mehr Flexibilität ermöglichen, den Zweck zu testen

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

Dank dafür. Das ist eine Herangehensweise, an die ich nicht gedacht hatte. Ich lese diese [Artikel] (https://msdn.microsoft.com/en-us/library/dn314429 (v = vs.113) .aspx # Anchor_7) auf MSDN. Ich frage mich, warum dieser andere Ansatz in meinem Fall nicht funktionieren könnte? Grundsätzlich verwenden sie einen Service, während ich Repository- und Arbeitsmodellmuster implementiere. Aber diese haben den gleichen Zweck: Modelle zu verwalten. Liege ich falsch ? – BertrandD

Verwandte Themen