2016-11-08 5 views
-1

Я пытаюсь создать тест для проверки структуры фрейма Add. Может кто-нибудь помочь, как издеваться над методом DbSet.Add. Я пробовал, как показано ниже, но не работал. Что я делаю не так?C# Как скомпоновать метод Moq DbSet Добавить метод

В результате я получаю null после repository.Insert ...

Test.cs:

var productToCreate = new Product { Name = "Added", Description = "Added" };   

var result = repository.InsertAsync(objToCreate, userContext).Result; 
Assert.AreEqual(result.Name, "Added"); 

Mock.cs

internal static DbSet<T> GetMockedDataSet<T>(IEnumerable<T> data) where T : class 
{ 
    // Create a mocked data set that contains the data 
    var set = new Mock<DbSet<T>>(); 
    set.As<IDbAsyncEnumerable<T>>() 
     .Setup(m => m.GetAsyncEnumerator()) 
     .Returns(new TestDbAsyncEnumerator<T>(data.GetEnumerator())); 
    set.As<IQueryable<T>>() 
     .Setup(m => m.Provider) 
     .Returns(new TestDbAsyncQueryProvider<T>(data.AsQueryable().Provider)); 
    set.As<IQueryable<T>>().Setup(m => m.Expression).Returns(data.AsQueryable().Expression); 
    set.As<IQueryable<T>>().Setup(m => m.ElementType).Returns(data.AsQueryable().ElementType); 
    set.As<IQueryable<T>>().Setup(m => m.GetEnumerator()).Returns(data.GetEnumerator()); 

    set.Setup(x => x.AsNoTracking()).Returns(set.Object); 
    set.Setup(x => x.Add(It.IsAny<T>())).Callback<T>((s) => data.Concat(new[] { s })); 

    // Return the mock 
    return set.Object; 
} 

Repository:

public async Task<Product> InsertAsync(Product input) 
{ 
    using (var ctx = .....)) 
    { 
     var added = ctx.Set<Product>().Add(input); 

     await ctx.ValidateAndSaveAsync(); 

     return added; 
    } 
} 
+1

Предоставить [mcve], который воспроизводит проблему. – Nkosi

+0

@Nkosi, Извините, я не понимаю, что вы имеете в виду? Я предоставил свой блок кода и объяснил, чего я ожидаю? Спасибо –

+1

Этот пример неполный. слишком много зависимых переменных неизвестны, чтобы иметь возможность воссоздать проблему, тестируемый метод отличается от того, что было показано в тесте, показанная установка неполна .... мне нужно продолжать? – Nkosi

ответ

2

Согласно тому, как метод Add используется в методе испытываемой ...

var added = ctx.Set<Product>().Add(input); 

... там тоже должно быть в установке, которая возвращает аргумент, который вступил в Returns, если это желательно функциональность.

set.Setup(x => x.Add(It.IsAny<T>())) 
    .Returns<T>(arg => arg) 
    .Callback<T>((s) => data.Concat(new[] { s })); 

Но, учитывая, что информация о контекстной зависимости неизвестна ...

using (var ctx = .....)) 

Сомнительно, если Предложенное решение будет иметь желаемый эффект.

Кроме того, при тестировании асинхронного метода не используйте асинхронные и синхронизирующие вызовы. Следующая строка ...

var result = repository.InsertAsync(objToCreate, userContext).Result; 

... может вызывать взаимоблокировки.

Выполните метод тестирования async полностью.

[TestMethod] 
public async Task InsertAsync_Should_Return_Product() { 
    //...other code 

    var expected = new Product { Name = "Added", Description = "Added" };   

    var actual = await repository.InsertAsync(expected, userContext); 

    Assert.AreEqual(expected.Name, actual.Name); 
} 
+0

Ничего себе! Он работал как шарм. Спасибо. Я изменил метод test для использования async. Еще раз спасибо –

+0

Боковое примечание. Обратный вызов метода добавления ничего не делает. он не влияет на исходную коллекцию. – Nkosi

Смежные вопросы