Рефакторинг C # Entity Framework 6 проект для использования зависимости зависимости для moqqing - PullRequest
0 голосов
/ 02 мая 2018

Я имею дело с добавлением инфраструктуры Dependancy Injection в большой проект, чтобы расширить охват модульного тестирования. В частности, я хочу рассказать о методе доступа к данным, поэтому я хочу иметь возможность Moq контекста.

Вот пример метода:

public int GetNumberOfLines(int groupId)
{
    using (var db = new EntitiesMigrate().AutoLocal())
    {
         return db.MergeUserLines.ByGroup(groupId).GroupBy(x => x.Number).Count();
    }
}

Метод AutoLocal() - это написанное мною расширение, которое позволяет нам использовать разные строки подключения в каждой среде env и на разных компьютерах разработчиков. Он используется на каждом new EntitiesMigrate() (просто говорю, может ли он помочь в moqqing). В настоящее время мы используем тестовый фреймворк Microsoft (внутри VS / 2017), но его использование не является обязательным для улучшения тестовых возможностей.

Мои вопросы:

  1. Каковы предпочтительные среды для объединения DI и MOQ в EF6 asp.net/mvc и asp.net/web-api?
  2. Как преобразовать этот метод, используя эти рамки?

1 Ответ

0 голосов
/ 02 мая 2018

Я получил интерфейс из моего контекста БД с IDbSets всех моих сущностей. Я внедряю этот интерфейс и использую его для всех моих запросов. Недостатком является то, что вы должны синхронизировать его с фактическим контекстом БД, если вносите изменения в базу данных.

public class EntitiesMigrate : IEntitiesMigrate
{
    public DbSet<MyEntity> MyEntities {get; set;}
    // or standardise on public IDbSet<MyEntity> MyEntities {get; set;}
    public DbSet<MergeUserLine> MergeUserLines { get; set; }
}

public interface IEntitiesMigrate
{
    DbSet<MyEntity> MyEntities {get; set;}
    // or standardise on IDbSet<MyEntity> MyEntities {get; set;}
    DbSet<MergeUserLine> MergeUserLines { get; set; }
    // Don't forget SaveChanges() and whatever else you need
}

// then remove this in your classes
using (var db = new EntitiesMigrate().AutoLocal())

// instead in your constructor
public class SomeClass
{
    public SomeClass(IEntitiesMigrate db)
    {
        _db = db;
    }
}

// then testing...
var db = new Mock<IEntitiesMigrate>();
var someOtherData = new Mock<DbSet<MergeUserLine>>(); 
// whereas IDbSet is easier to mock, DbSet will give you all the properties and methods you need. 
// see https://msdn.microsoft.com/en-us/library/dn314429(v=vs.113).aspx for setting up mock DbSets
db.Setup(d=> d.MyEntities).Returns(someData.Object);
db.Setup(d=> d.MergeUserLines).Returns(someOtherData.Object);

Ваш пробег может отличаться, но это хорошо работает для насмешек.

Редактировать

Я изменил IDbSet<T> на DbSet<T>

...