Подтвердить что ты не робот

Mock DbContext.set <T>.Add() EF6

У меня есть следующие классы (где PilsnerContext - это класс DbContext):

public abstract class ServiceBase<T> : IService<T> where T: class, IEntity
{
    protected readonly PilsnerContext Context;

    protected ServiceBase(PilsnerContext context)
    {
        Context = context;
    }

    public virtual T Add(T entity)
    {
        var newEntity = Context.Set<T>().Add(entity);
        Context.SaveChanges();
        return newEntity;
    }
}

public class ProspectsService : ServiceBase<Prospect>
{
    public ProspectsService(PilsnerContext context) : base(context){}

}

И я пытаюсь сделать unit test метода Add, издевающегося над контекстом, например:

[TestClass]
public class ProspectTest
{
    [TestMethod]
    public void AddProspect()
    {
        var mockProspect = new Mock<DbSet<Prospect>>();
        var mockContext = new Mock<PilsnerContext>();

        mockContext.Setup(m => m.Prospects).Returns(mockProspect.Object);

        var prospectService = new ProspectsService(mockContext.Object);

        var newProspect = new Prospect()
        {
            CreatedOn = DateTimeOffset.Now,
            Browser = "IE",
            Number = "1234567890",
            Visits = 0,
            LastVisitedOn = DateTimeOffset.Now
        };

        prospectService.Add(newProspect);

        mockProspect.Verify(m=>m.Add(It.IsAny<Prospect>()), Times.Once);
        mockContext.Verify(m=>m.SaveChanges(), Times.Once);
    }
}

Но утверждение:

mockProspect.Verify(m=>m.Add(It.IsAny<Prospect>()), Times.Once);

Я ошибаюсь, полагаю, потому, что я использую Context.set(). Добавить() вместо Context.Prospects.Add() в методе добавления, но как правильно пройти этот тест?

Исключение составляет:

Expected invocation on the mock once, but was 0 times: m => m.Add(It.IsAny<Prospect>()) No setups configured. No invocations performed.

Спасибо заранее.

4b9b3361

Ответ 1

Я попробовал ваше решение Patrick Quirk, но у меня возникла ошибка, говорящая мне, что DbContext.Set не является виртуальным.

Я нашел решение для этого здесь:

Как обмануть Entity Framework 6 Асинхронные методы?

Создание интерфейса DbContext, например

    public interface IPilsnerContext
   {
       DbSet<T> Set<T>() where T : class;
   }

Таким образом, я мог бы издеваться над этим.

Спасибо!

Это мой первый вопрос кстати, я не уверен, могу ли я отметить этот вопрос как дублированный или что-то в этом роде.

Ответ 2

Похоже, вы просто пропустили настройку, чтобы вернуть свой DbSet:

mockContext.Setup(m => m.Set<Prospect>()).Returns(mockProspect.Object);