Ich erstelle ein GenericRepository mit EF und schreibe Unit Tests zum ersten Mal. Tests für GetAll()
und Update()
bestanden, aber Add()
und Delete()
fehlgeschlagen. Warum ist es nicht Add
? Ich ziehe mir die Haare aus, weil es eine Codezeile ist und ich es nicht herausfinden konnte. Ich benutze EF Datenbank zuerst, Nunit, Nsubstitute.Generisches Repository fügt keine Entität zum Kontext beim Testen hinzu
Jeder Rat ist willkommen.
public class GenericDataRepository<T, C> : IGenericDataRepository<T, C> where T : class where C : DbContext, new() {
protected C _context;
protected IDbSet<T> _dbSet;
public GenericDataRepository() {
_context = new C();
_dbSet = _context.Set<T>();
}
public GenericDataRepository(C context) {
_context = context;
_dbSet = context.Set<T>();
}
public virtual IQueryable<T> GetAll() {
return _dbSet.AsQueryable<T>();
}
public virtual T Add(T entity) {
return _dbSet.Add(entity);
}
public virtual void Update(T entity) {
_context.Entry(entity).State = EntityState.Modified;
}
public virtual T Delete(T entity) {
return _dbSet.Remove(entity);
}
public virtual void Save() {
_context.SaveChanges();
}
}
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; }
Tests
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
}
Passt Ihr 'Customer'-Typ zum entsprechenden Entitätstyp? –
Ich habe nicht alle Eigenschaften in "Kunde" aufgenommen. Einige der Felder können nicht null sein. Aber 'repo.Save()' hat keine Ausnahme ausgelöst. – Firefly
Sorry, um zu verdeutlichen, muss der 'Customer'-Typ derselbe Typ sein, der im Entity-Framework einer Tabelle zugeordnet ist. Wie haben Sie Ihren Kontext abgebildet? Verwenden Sie Database-First oder Code-First? –