2014-12-05 14 views
3

Я пытаюсь следовать this Приступить к примеру для тестирования с помощью Moq. Я могу дублировать примеры в моем собственном проекте тестирования и могу пройти тесты (тестирование моей службы, в которой мой контекст вводится). Однако то, что я не понимаю, когда использовать каждый из следующих вызовов Setup:Когда указывать определенные настройки в Moq

var mockSet = new Mock<DbSet<Blog>>(); 
mockSet.As<IQueryable<Blog>>().Setup(m => m.Provider).Returns(data.Provider); 
mockSet.As<IQueryable<Blog>>().Setup(m => m.Expression).Returns(data.Expression); 
mockSet.As<IQueryable<Blog>>().Setup(m => m.ElementType).Returns(data.ElementType); 
mockSet.As<IQueryable<Blog>>().Setup(m => m.GetEnumerator()).Returns(data.GetEnumerator()); 

Может кто-то объяснить очень основные термины, как, когда каждый из них следует использовать?

Например, кажется, что если метод в моей службе, который я тестирую, использует выражение, мне нужно выполнить второй установочный вызов выше (я сделал пробную версию и ошибку, удалив и повторно вставив эти звонки). Я был в документации Moq, а также MSDN для Table-TEntity, и я до сих пор не вижу его. Возможно, потому, что у меня нет сильного понимания пространства имен Linq.

+0

Вам нужно указать только то, что вам нужно ....? – Swati

+0

Вот что я не уверен. Я не уверен, что каждый делает. Я хотел бы получить общее объяснение того, когда использовать их. Имеют смысл? –

ответ

3

TL; DR - При использовании Entity Framework DBContext зависимости, вам нужно будет выполнять эти аккомпанемента на любом DBSet, который вы собираетесь дразнить, в частности, чтобы вернуть поддельные данные на любые запросы LINQ на DBSet. Все 4 установки должны быть выполнены для каждого из насмешанного DbSet - это можно сделать в общем случае вспомогательным методом.

более подробно:

В общем, с Strict mode off, программа установки требуется только на методы, которые вы на самом деле хотите, чтобы дразнить. В этом случае, если вы еще не сделали Setup по методу, который вызывается во время вашего модульного теста, Moq вместо этого будет предоставлять поведение по умолчанию для любого метода, который не был явно Setup, который обычно должен возвращать default(T) любых ожидаемых return type, T. Для классов значение по умолчанию равно null, что на самом деле не поможет при тестировании классов, зависящих от Mocked EF DbContext.

Конкретный пример вы предоставили стандартный mocked setup for an Entity Framework DbSet, который затем позволяет предоставлять поддельные данные для этой конкретной DbSet (DbSet<Blog>), предоставляя альтернативный IQueryable<Blog> из List<Blog> коллекции (в отличие от обычной конкретной реализации СУБД) ,

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

public static Mock<IDbSet<T>> GetMockedDbSet<T>(IList<T> fakeData) where T : class, new() 
{ 
    var data = fakeData.AsQueryable(); 

    var mockSet = new Mock<IDbSet<T>>(); 
    mockSet.As<IQueryable<T>>().Setup(m => m.Provider).Returns(data.Provider); 
    mockSet.As<IQueryable<T>>().Setup(m => m.Expression).Returns(data.Expression); 
    mockSet.As<IQueryable<T>>().Setup(m => m.ElementType).Returns(data.ElementType); 
    mockSet.As<IQueryable<T>>().Setup(m => m.GetEnumerator()).Returns(data.GetEnumerator()); 

    return mockSet; 
} 

Что вы можете настроить по своему Mock DBContext, следующим образом:

var mockContext = new Mock<IMyDbContext>(); 
var mockBlogDbSet = GetMockedDbSet<Blog>(new List<Blog>{... fake data here ...}); 
mockContext.Setup(c => c.Blogs).Returns(mockBlogDbSet.Object); 

var sut = new SomeClassIWantToTest(mockContext.Object); // Inject dependency into Ctor 
sut.DoSomething();... 
Смежные вопросы