Ich möchte etwas Code testen, und um das zu erreichen, müsste ich DbContext fälschen, der in DAL definiert ist ( Entity Framework 6 - Code first
). Es läuft meistens gut, aber ich stieß auf ein Problem, wenn die Datenmodellklasse das TypeName
Attribut verwendet. Ich machte ein Skelett, um das Problem zu demonstrieren.
Das Datenmodell:
[Table("Customer")]
public class Customer
{
[Key]
public int Id { get; set; }
public string FirstName{ get; set; }
public string LastName { get; set; }
//this line causes the exception
[Column(TypeName = "money")]
public decimal Salary { get; set; }
}
Die Kontextdefinition
public class MyDbContext : DbContext
{
public MyDbContext(string nameOrConnectionString) : base(nameOrConnectionString)
{
}
public MyDbContext(DbConnection connection) : base(connection, true)
{
}
public IDbSet<Customer> Customers { get; set; }
}
Und eine Dummy-Methode, um einen gefälschten Kontext mit einigen Daten zu generieren:
private MyDbContext GenerateFakeDbContext()
{
var connection = DbConnectionFactory.CreateTransient();
var context = new MyDbContext(connection);
var customer = new Customer
{
Id = 1,
FirstName = "X",
LastName = "Y",
Salary = 1000
};
//this line throws the exception
context.Customers.Add(customer);
return context;
}
Das Problem ist das TypeName
Attribut. Wenn es auskommentiert wird, bestehen Tests. Aber wenn es aktiviert ist, habe ich eine System.InvalidOperationException
ausgelöst und gesagt
Sequenz enthält keine passenden Element
Um es zusammenzufassen, meine Fragen sind:
Ich würde Ihnen empfehlen, sich EntityTypeConfigurations anzuschauen und Ihre Mappings dorthin zu verschieben: http://www.entityframeworktutorial.net/code-first/entitytypeconfiguration-class.aspx
Es ermöglicht Ihnen, Ihre aktuelle verwendete Datenbank nicht zu berücksichtigen und Ihre Entitäten / Schnittstellen zu testen, ohne sie mit Entity Framework zu berücksichtigen.
Es sieht auch so aus, dass Sie Integrationstests anstelle von Komponententests durchführen. Um Komponententests durchzuführen, sollten Sie die echte DbContext-Verwendung loswerden (Ihre aktuelle Implementierung verwendet eine konkrete EF-Implementierung für DAL, sollte aber stattdessen eine Abstraktion verwenden).
Ich würde empfehlen, dass Sie Ihren DbContext zumindest in eine Oberfläche einbinden, damit Sie ihn besser machen / stupsen können:
public interface IDbContext {
IDbSet<Customer> Customers { get; set; }
}