2016-06-04 9 views
3

Ich verwende Entity Framework 7 in .net Core 1.0 rc2. Hier ist die Klasse.Wie matcht man dbcontext?

public class ApplicationDbContext : DbContext 
{ 
    public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options) : base(options) 
    { 

    } 
    public DbSet<Blog> Blogs { get; set; } 
} 

dann die ApplicationDbContext zu einer Klasse

public class BtnValidator 
{ 
    private readonly ApplicationDbContext _dbContext; 
    public BtnValidator(ApplicationDbContext dbContext) 
    { 
     _dbContext = dbContext; 
    } 
} 

Nicht sicher injizieren, wie es in Unit-Test-Methode zu verspotten.

[Fact] 
public void Ensure_Proper_Btn_Validated_Return_True() 
{ 
    var dbContext = mockup(ApplicationDbContext); //how 

    var validator = new BtnValidator(dbContext); 
    var results = validator.IsValid("1234"); 
    Assure.True(results); 
} 

EDIT

In BtnValidator habe ich Code die dbContext zuzugreifen.

public IsValid(string ID) 
{ 
    var results = _dbContext.Blogs.First(x => x.ID); 
    // 
} 
+0

Es ist kein Mock, sondern prüfen, mit in- Speicheranbieter für EF (Aufwand - https://effort.codeplex.com/). Gut für Unit-Test EF-Code. – Evk

+0

@Evk, es gibt zwei Dinge. Eine ist, ich benötige Unit-Test, Zweitens verwende ich .Net-Core 1.0 RC2, die Bibliothek vielleicht nicht unterstützt. –

+0

Vielleicht ist es an dieser Stelle nicht praktisch für Sie, aber überlegen Sie sich, ein Repository-Muster zu verwenden. Dann verspotten Sie das Repo, nicht den tatsächlichen Datenbankzugriff. – Crowcoder

Antwort

8

Sie könnten Ihren DbContext abstrahieren, um ihn anschaulich zu machen.

public interface IDbContext { 
    DbSet<Blog> Blogs { get; set; } 
    //...other properties and members needed for db context 
    int SaveChanges(); 
} 

public class ApplicationDbContext : DbContext, IDbContext 
{ 
    public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options) : base(options) { 

    } 

    public DbSet<Blog> Blogs { get; set; } 
} 

Sie dann den Auftrag in abhängigen Klassen injizieren

public class BtnValidator { 
    private readonly IDbContext _dbContext; 

    public BtnValidator(IDbContext dbContext) { 
     _dbContext = dbContext; 
    } 

    public bool IsValid(string ID) { 
     var result = _dbContext.Blogs.FirstOrDefault(x => x.ID == ID); 
     return result != null; 
    } 
} 

und dann können verspotten Sie in Ihrer Unit-Tests die Schnittstellen

[Fact] 
public void Ensure_Proper_Btn_Validated_Return_True() { 
    //Arrange 
    var id = "1234" 
    var blogsTestData = new List<Blog>(){ new Blog { ID = id } }; 
    var blogs = MockDbSet(blogsTestData); 
    //Set up mocks for db sets 
    var dbContext = new Mock<IDbContext>();   
    dbContext.Setup(m => m.Blogs).Returns(blogs.Object); 

    var validator = new BtnValidator(dbContext.Object); 

    //Act 
    var results = validator.IsValid(id); 

    //Assert 
    Assure.True(results); 
} 

Mock<DbSet<T>> MockDbSet<T>(IEnumerable<T> list) where T : class, new() { 
    IQueryable<T> queryableList = list.AsQueryable(); 
    Mock<DbSet<T>> dbSetMock = new Mock<DbSet<T>>(); 
    dbSetMock.As<IQueryable<T>>().Setup(x => x.Provider).Returns(queryableList.Provider); 
    dbSetMock.As<IQueryable<T>>().Setup(x => x.Expression).Returns(queryableList.Expression); 
    dbSetMock.As<IQueryable<T>>().Setup(x => x.ElementType).Returns(queryableList.ElementType); 
    dbSetMock.As<IQueryable<T>>().Setup(x => x.GetEnumerator()).Returns(() => queryableList.GetEnumerator()); 
    dbSetMock.Setup(x => x.Create()).Returns(new T()); 

    return dbSetMock; 
}