Исключение, запрашивающее контекст Mocked Entity Framework

Когда я создаю экземпляр Mock с помощью MockBehavior.Strict, я получаю сообщение об ошибке

Исключение типа «Moq.MockException» возникло в Moq.dll, но не было обработано в пользовательском коде.

Дополнительная информация: не удалось вызвать DbContext.Set() из-за фиктивного поведения Strict.

Все вызовы макета должны иметь соответствующую настройку.

Но я уже сделал настройку для каждой таблицы, включая эту:

        var mockContext = new Mock<JournalsDB>(MockBehavior.Strict);
        mockContext.Setup(m => m.Publications).Returns(mockPublicationSet.Object);
        mockContext.Setup(m => m.Journals).Returns(mockJournalSet.Object);
        mockContext.Setup(m => m.AspNetUsers).Returns(mockUserSet.Object);
        mockContext.Setup(m => m.AspNetRoles).Returns(mockRoleSet.Object);
        mockContext.Setup(m => m.AspNetUserClaims).Returns(mockClaimSet.Object);
        mockContext.Setup(m => m.AspNetUserLogins).Returns(mockLoginSet.Object);

Я подозреваю, что проблема может быть связана с моей реализацией репозитория или реализацией DbContext:

        public class JournalRepository<DataObject, DataContext> :    IRepository<DataObject, DataContext>, IDisposable
 where DataObject : class
 where DataContext : DbContext
{
    #region Propiedades

    private readonly DataContext _ctx;

так далее...

 public partial class JournalsDB : DbContext
 {
    public JournalsDB()
        : base("name=JournalsDB")
    {
    }

    public JournalsDB(string connectionName)
        : base(connectionName)
    {

    }

так далее...

РЕДАКТИРОВАТЬ:

Без MockBehaviour.Strict я получаю сообщение об ошибке. Значение не может быть нулевым. Имя параметра: источник при запросе любого DbSet, но наборы DbSet заполнены правильно.

Ошибка обращения к DbSet


person Boanerge    schedule 13.08.2016    source источник


Ответы (1)


Честно говоря, я действительно думаю, что вы выбрали неправильный подход. Насмешка над DbContext действительно болезненна, потому что это очень широкий интерфейс. Это действительно тот случай, когда вы пытаетесь имитировать интерфейс, которым вы не владеете. Насмешка над чужим интерфейсом всегда ведет к неприятностям. В случае с DbContext вы действительно хотели бы также издеваться над поведением таких вызовов, как SaveChanges().

Я бы изолировал использование DbContext за гораздо меньшим интерфейсом, который легче высмеивать. Затем у вас будет два типа тестов, которые вы хотите написать:

  1. Модульное тестирование всего, что использует новый интерфейс. Эти тесты будет проще написать, потому что вам не придется создавать фиктивные DbContext

  2. Протестируйте класс, который реализует интерфейс, используя реальную базу данных с реальными данными в ней. Таким образом, вы можете протестировать уровень доступа к данным изолированно.

Более подробное объяснение см. в ответе, который я написал здесь: - FirstOrDefault возвращает null при подделке базы данных

person AggieEric    schedule 14.08.2016
comment
У меня была не очень хорошая реализация шаблона репозитория. Прямо сейчас я переписываю этот код, чтобы избежать зависимости в объекте DbContext. Спасибо за вашу помощь. - person Boanerge; 19.08.2016
comment
Ага. Если вы имитируете принадлежащие вам интерфейсы, вы можете контролировать, изменяют ли они свой контракт. Но чужие интерфейсы или объекты, обновление с критическими изменениями в API также сломают ваши тесты, которые имитируют их API иногда тонкими и разочаровывающими способами. Мой общий подход всегда заключался в том, чтобы обернуть классы внешних служб в классы, которые я объявляю и для которых контролирую интерфейс. Другими словами, я пытаюсь ограничить площадь внешней зависимости. Это почти всегда приводило к более стабильной базе кода для меня. - person AggieEric; 20.08.2016