[英]How to Unit Test with Dynamically-Generated ADO.NET Entity Data Model Code
I'm following this tutorial which explains how to mock the entity framework when performing unit testing on a Web API 2 service. 我正在遵循本教程 , 该教程说明了在Web API 2服务上执行单元测试时如何模拟实体框架。
The code works by using dependency injection by defining an interface 该代码通过定义接口使用依赖项注入来工作
namespace StoreAcreTransmissions.Models
{
public interface IStoreAcreTransmissionsContext : IDisposable
{
DbSet<AcreReportTransaction> AcreReportTransactions { get; }
int SaveChanges();
void MarkAsModified(AcreReportTransaction item);
}
}
that is then implemented by a 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;
}
}
}
and passed to the constructor of the Controller 并传递给Controller的构造函数
public AcreReportTransactionsController(IStoreAcreTransmissionsContext context)
{
db = context;
}
All this works great, but in the normal operation of the service I'm utilizing an auto-generated ADO Entity Data Model to communicate with the database. 所有这些工作都很好,但是在服务的正常运行中,我正在利用自动生成的ADO实体数据模型与数据库进行通信。 So in order for me to use the actual Data Model in my controller, I have to set it in the default constructor:
因此,为了让我在控制器中使用实际的数据模型,必须在默认构造函数中进行设置:
private IStoreAcreTransmissionsContext db;
public AcreReportTransactionsController()
{
db = new DataModelContext();
}
But I also have to modify the dynamically generated context class ( AcreReportTransactionModel.Context.cs ) that is generated by the model so that it also implements the IStoreAcreTransmissionsContext interface: 但是我还必须修改由模型生成的动态生成的上下文类( 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;
}
}
}
The problem is, every time I re-sync my model with the database, this dynamically-generated context class is re-created and the code I added to implement the IStoreAcreTransmissionsContext interface is removed. 问题是,每次我将模型与数据库重新同步时,都会重新创建此动态生成的上下文类,并且删除为实现IStoreAcreTransmissionsContext接口而添加的代码。
How can I configure my code such that the unit tests work and I can re-generate my model without having to re-add code? 如何配置代码以使单元测试正常工作,并且无需重新添加代码就可以重新生成模型?
You shouldn't modify the generated code. 您不应该修改生成的代码。 Modify the template used to generate the code.
修改用于生成代码的模板。
In the Solution Explorer open the tree of your EDMX-Model, here you find a file named *.Context.tt, open it and modify the appropriate section. 在解决方案资源管理器中,打开EDMX模型的树,在这里找到一个名为* .Context.tt的文件,将其打开并修改相应的部分。
You can see that the generated context class includes the partial
keyword. 您可以看到生成的上下文类包括
partial
关键字。 This means you can, in a new file, declare the following: 这意味着您可以在一个新文件中声明以下内容:
public partial class ACRSIEntities : IStoreAcreTransmissionsContext {
// Implement missing methods
public void MarkAsModified(AcreReportTransaction item)
{
Entry(item).State = EntityState.Modified;
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.