jeudi 22 janvier 2015

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.


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://ift.tt/1d6OWUZ

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



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. 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:



//------------------------------------------------------------------------------
// <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.


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?


Aucun commentaire:

Enregistrer un commentaire