如何使用动态生成的 ADO.NET 实体数据模型代码进行单元测试
How to Unit Test with Dynamically-Generated ADO.NET Entity Data Model Code
我正在关注 this tutorial,它解释了在 Web API 2 服务上执行单元测试时如何模拟 entity framework。
代码通过定义接口使用依赖注入来工作
namespace StoreAcreTransmissions.Models
{
public interface IStoreAcreTransmissionsContext : IDisposable
{
DbSet<AcreReportTransaction> AcreReportTransactions { get; }
int SaveChanges();
void MarkAsModified(AcreReportTransaction item);
}
}
然后由 class
实现
namespace StoreAcreTransmissions.Models
{
public class StoreAcreTransmissionsContext : DbContext, IStoreAcreTransmissionsContext
{
// You can add custom code to this file. Changes will not be overwritten.
//
// If you want Entity Framework to drop and regenerate your database
// automatically whenever you change your model schema, please use data migrations.
// For more information refer to the documentation:
// http://msdn.microsoft.com/en-us/data/jj591621.aspx
public StoreAcreTransmissionsContext() : base("name=StoreAcreTransmissionsContext")
{
}
public System.Data.Entity.DbSet<StoreAcreTransmissions.Models.AcreReportTransaction> AcreReportTransactions { get; set; }
public void MarkAsModified(AcreReportTransaction item)
{
Entry(item).State = EntityState.Modified;
}
}
}
并传递给Controller的构造函数
public AcreReportTransactionsController(IStoreAcreTransmissionsContext context)
{
db = context;
}
这一切都很好,但在服务的正常运行中,我使用自动生成的 ADO 实体数据模型与数据库进行通信。所以为了让我在我的控制器中使用实际的数据模型,我必须在默认构造函数中设置它:
private IStoreAcreTransmissionsContext db;
public AcreReportTransactionsController()
{
db = new DataModelContext();
}
但我还必须修改由模型生成的动态生成的上下文 class (AcreReportTransactionModel.Context.cs),以便它也实现 IStoreAcreTransmissionsContext接口:
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated from a template.
//
// Manual changes to this file may cause unexpected behavior in your application.
// Manual changes to this file will be overwritten if the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace StoreAcreTransmissions.Models
{
using System;
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
public partial class ACRSIEntities : DbContext, IStoreAcreTransmissionsContext
{
public ACRSIEntities()
: base("name=ACRSIEntities")
{
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
throw new UnintentionalCodeFirstException();
}
public virtual DbSet<AcreReportTransaction> AcreReportTransactions { get; set; }
public void MarkAsModified(AcreReportTransaction item)
{
Entry(item).State = EntityState.Modified;
}
}
}
问题是,每次我将我的模型与数据库重新同步时,都会重新创建这个动态生成的上下文 class 并且我添加的用于实现 IStoreAcreTransmissionsContext 接口的代码被删除。
我如何配置我的代码,以便单元测试工作,并且我可以重新生成我的模型而无需重新添加代码?
您不应修改生成的代码。修改用于生成代码的模板。
在解决方案资源管理器中打开您的 EDMX 模型树,在这里您可以找到一个名为 *.Context.tt 的文件,打开它并修改相应的部分。
您可以看到生成的上下文 class 包含 partial
关键字。这意味着您可以在新文件中声明以下内容:
public partial class ACRSIEntities : IStoreAcreTransmissionsContext {
// Implement missing methods
public void MarkAsModified(AcreReportTransaction item)
{
Entry(item).State = EntityState.Modified;
}
}
在 MSDN
中有更多关于部分 class 的内容
我正在关注 this tutorial,它解释了在 Web API 2 服务上执行单元测试时如何模拟 entity framework。
代码通过定义接口使用依赖注入来工作
namespace StoreAcreTransmissions.Models
{
public interface IStoreAcreTransmissionsContext : IDisposable
{
DbSet<AcreReportTransaction> AcreReportTransactions { get; }
int SaveChanges();
void MarkAsModified(AcreReportTransaction item);
}
}
然后由 class
实现namespace StoreAcreTransmissions.Models
{
public class StoreAcreTransmissionsContext : DbContext, IStoreAcreTransmissionsContext
{
// You can add custom code to this file. Changes will not be overwritten.
//
// If you want Entity Framework to drop and regenerate your database
// automatically whenever you change your model schema, please use data migrations.
// For more information refer to the documentation:
// http://msdn.microsoft.com/en-us/data/jj591621.aspx
public StoreAcreTransmissionsContext() : base("name=StoreAcreTransmissionsContext")
{
}
public System.Data.Entity.DbSet<StoreAcreTransmissions.Models.AcreReportTransaction> AcreReportTransactions { get; set; }
public void MarkAsModified(AcreReportTransaction item)
{
Entry(item).State = EntityState.Modified;
}
}
}
并传递给Controller的构造函数
public AcreReportTransactionsController(IStoreAcreTransmissionsContext context)
{
db = context;
}
这一切都很好,但在服务的正常运行中,我使用自动生成的 ADO 实体数据模型与数据库进行通信。所以为了让我在我的控制器中使用实际的数据模型,我必须在默认构造函数中设置它:
private IStoreAcreTransmissionsContext db;
public AcreReportTransactionsController()
{
db = new DataModelContext();
}
但我还必须修改由模型生成的动态生成的上下文 class (AcreReportTransactionModel.Context.cs),以便它也实现 IStoreAcreTransmissionsContext接口:
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated from a template.
//
// Manual changes to this file may cause unexpected behavior in your application.
// Manual changes to this file will be overwritten if the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace StoreAcreTransmissions.Models
{
using System;
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
public partial class ACRSIEntities : DbContext, IStoreAcreTransmissionsContext
{
public ACRSIEntities()
: base("name=ACRSIEntities")
{
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
throw new UnintentionalCodeFirstException();
}
public virtual DbSet<AcreReportTransaction> AcreReportTransactions { get; set; }
public void MarkAsModified(AcreReportTransaction item)
{
Entry(item).State = EntityState.Modified;
}
}
}
问题是,每次我将我的模型与数据库重新同步时,都会重新创建这个动态生成的上下文 class 并且我添加的用于实现 IStoreAcreTransmissionsContext 接口的代码被删除。
我如何配置我的代码,以便单元测试工作,并且我可以重新生成我的模型而无需重新添加代码?
您不应修改生成的代码。修改用于生成代码的模板。
在解决方案资源管理器中打开您的 EDMX 模型树,在这里您可以找到一个名为 *.Context.tt 的文件,打开它并修改相应的部分。
您可以看到生成的上下文 class 包含 partial
关键字。这意味着您可以在新文件中声明以下内容:
public partial class ACRSIEntities : IStoreAcreTransmissionsContext {
// Implement missing methods
public void MarkAsModified(AcreReportTransaction item)
{
Entry(item).State = EntityState.Modified;
}
}
在 MSDN
中有更多关于部分 class 的内容