Entity framework 6 mocking включает метод на dbset

c# entity-framework-6

Вопрос

Были googling для решения проблемы о том, как издеваться над методом include на dbset в EF6. Проблема хорошо документирована здесь: -

http://entityframework.codeplex.com/discussions/461731

К сожалению, хотя там, похоже, не существует правильного решения.

Кто-нибудь нашел обходное решение?

Я понимаю, что мы действительно не должны насмехаться над EF6, но руководство проекта настаивало на этом.

Заранее спасибо.

Принятый ответ

Итак, это возможно, если немного издевательства!

В нижеследующем я устанавливаю макет контекста и устанавливает и может звонить успешно. Я думаю, что секретный соус заключает вызовы через Provider, Expression и GetEnumerator и в настройке свойств DbSet на заштрихованном контексте на оштукатуренные множества, а не на укорачивание контекста для их возврата.

Простой пример доступен на GitHub

    [Test]
    public void CanUseIncludeWithMocks()
    {
        var child = new Child();
        var parent = new Parent();
        parent.Children.Add(child);

        var parents = new List<Parent>
            {
                parent
            }.AsQueryable();

        var children = new List<Child>
            {
                child
            }.AsQueryable();

        var mockContext = MockRepository.GenerateStub<TestContext>();

        var mockParentSet = MockRepository.GenerateStub<IDbSet<Parent>>();
        var mockChildSet = MockRepository.GenerateStub<IDbSet<Child>>();

        mockParentSet.Stub(m => m.Provider).Return(parents.Provider);
        mockParentSet.Stub(m => m.Expression).Return(parents.Expression);
        mockParentSet.Stub(m => m.GetEnumerator()).Return(parents.GetEnumerator());

        mockChildSet.Stub(m => m.Provider).Return(children.Provider);
        mockChildSet.Stub(m => m.Expression).Return(children.Expression);
        mockChildSet.Stub(m => m.GetEnumerator()).Return(children.GetEnumerator());

        mockContext.Parents = mockParentSet;
        mockContext.Children = mockChildSet;

        mockContext.Parents.Should().HaveCount(1);
        mockContext.Children.Should().HaveCount(1);

        mockContext.Parents.First().Children.FirstOrDefault().Should().NotBeNull();

        var query = mockContext.Parents.Include(p=>p.Children).Select(pc => pc);

        query.Should().NotBeNull().And.HaveCount(1);
        query.First().Children.Should().NotBeEmpty().And.HaveCount(1);

    }

Популярные ответы

У меня была та же драма, что и @GetFuzzy выше - казалось, что независимо от того, что я делал, я не мог избежать исключения NullReferenceException всякий раз, когда был вызван вызов Include () на Moq DbSet. Пример Github в другом ответе, к сожалению, не сработал: Set.Include () всегда возвращает null.

Поймав какое-то время, я придумал обходной путь для этого.

[Test]
public void CanUseIncludeWithMocks()
{
    var child = new Child();
    var parent = new Parent();
    parent.Children.Add(child);

    var parents = new List<Parent> { parent };
    var children = new List<Child> { child };

    var parentsDbSet1 = new FakeDbSet<Parent>();
    parentsDbSet1.SetData(parents);

    var parentsDbSet2 = new FakeDbSet<Parent>();
    parentsDbSet2.SetData(parents);

    parentsDbSet1.Setup(x => x.Include(It.IsAny<string>())).Returns(parentsDbSet2.Object);

    // Can now test a method that does something like: context.Set<Parent>().Include("Children") etc
}


public class FakeDbSet<T> : Mock<DbSet<T>> where T : class
{
    public void SetData(IEnumerable<T> data)
    {
        var mockDataQueryable = data.AsQueryable();

        As<IQueryable<T>>().Setup(x => x.Provider).Returns(mockDataQueryable.Provider);
        As<IQueryable<T>>().Setup(x => x.Expression).Returns(mockDataQueryable.Expression);
        As<IQueryable<T>>().Setup(x => x.ElementType).Returns(mockDataQueryable.ElementType);
        As<IQueryable<T>>().Setup(x => x.GetEnumerator()).Returns(mockDataQueryable.GetEnumerator());
    }
}

Мне действительно не нравится неуклюжесть необходимости иметь два поддельных DbSets, но по какой-то причине это не работает:

parentsDbSet1.Setup(x => x.Include(It.IsAny<string>())).Returns(parentsDbSet1.Object);

у кого есть объяснение?



Лицензировано согласно: CC-BY-SA with attribution
Не связан с Stack Overflow
Является ли этот КБ законным? Да, узнайте, почему
Лицензировано согласно: CC-BY-SA with attribution
Не связан с Stack Overflow
Является ли этот КБ законным? Да, узнайте, почему