Перемешивание Сервиса с использованием Moq в C # - PullRequest
0 голосов
/ 13 декабря 2018

У меня есть служба, настроенная таким образом.

public Interface IDataService : IDisposable
{
    IQueryable<T> Set<T>() where T : class;

    IDbSet<T> WritableSet<T>() where T : class;
}

IDataService наследуется DataService.

public abstract class DataService : IDataService
{
    public IDataContext DataContext { get; private set; }

    public IQueryable<T> Set<T>() where T : class
    {
        return DataContext.Set<T>().AsNoTracking();
    }

    public IDbSet<T> WritableSet<T>() where T : class
    {
        return DataContext.Set<T>();
    }

    public AddResult<T> Add<T>(T obj) where T : class, IPersistentEntity
    {
        if (obj == null)
            return new AddResult<T>() { IsValid = false };
        else
        {
            if (obj.Id == Guid.Empty)
                WritableSet<T>().Add(obj);

            bool success = DataContext.SaveChanges() > 0;

            return new AddResult<T>() { Entity = obj, IsValid = success };
        }
    }
}

А DataService наследуется EntityService.

public class EntityService : DataService
{
    public EntityService(IDataContext DataContext) : base(DataContext)
    {
    }

    public void EntityStarted(Guid Id)
    {
        var a = GetWriteableById<Entity>(Id);
        a.Status = 1;
        DataContext.SaveChanges();
    }
}

Этот EntityService используется в одном из моих компонентов.Объект EntityService создается и передается в конструктор компонента.

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

Наименее привлекательная идея, которая у меня есть, - создать поддельный класс EntityService с использованием интерфейса и иметь собственную реализацию, подходящую длятесты.

Помощь приветствуется!:)

Ответы [ 2 ]

0 голосов
/ 13 декабря 2018

В соответствии с комментариями @JLe и @ Chetan к этому вопросу, мне пришлось высмеивать DbContext.Я следовал этой статье, чтобы издеваться над DbContext.

Перемешивание DbContext с Moq

Вот как выглядит код.

    private void Setup()
    {
        List<Entity> entityData = new List<Entity>();
        entityData.Add(new Entity
        {
            Id = Guid.NewGuid()
        });

        DbSet<Entity> MockEntitySet = GetSet(entityData);

        MockContext = new Mock<IDbContext>();
        MockContext.Setup(m => m.Set<Entity>()).Returns(MockEntitySet);
    }

    public static DbSet<T> GetSet<T>(List<T> sourceList) where T : class
    {
        return GetSet(sourceList.ToArray());
    }

    public static DbSet<T> GetSet<T>(T[] sourceList) where T : class
    {
        var name = typeof(T).Name;

        var queryable = sourceList.AsQueryable();

        Mock<DbSet<T>> dbSet = new Mock<DbSet<T>>();

        dbSet.As<IQueryable<T>>().Setup(m => m.Provider).Returns(queryable.Provider);
        dbSet.As<IQueryable<T>>().Setup(m => m.Expression).Returns(queryable.Expression);
        dbSet.As<IQueryable<T>>().Setup(m => m.ElementType).Returns(queryable.ElementType);
        dbSet.As<IQueryable<T>>().Setup(m => m.GetEnumerator()).Returns(queryable.GetEnumerator());

        dbSet.Setup(m => m.AsNoTracking()).Returns(dbSet.Object);

        return dbSet.Object;
    }

    [TestMethod]
    public void Test()
    {
        EntityService service = new EntityService(MockContext.Object);
        ComponentToTest compObj = new ComponentToTest(service);
        compObj.MethodToTest(...);

        // Assertions
    }

Спасиборебята!Ценю вашу помощь и предложения.

0 голосов
/ 13 декабря 2018

Чтобы имитировать, вам нужен интерфейс, если нет, вам нужно пометить методы, которые вы хотите имитировать, как виртуальные.

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

Надеюсь, это поможет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...