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

Как я высмеиваю IQueryable <T>

Я создаю репозиторий, который предоставляет IQueryable. Каков наилучший способ издеваться над этим модульным тестированием?

Так как я использую RhinoMocks для остальных моих макетных объектов, я попытался сделать следующее:

IQueryable<MyObject> QueryObject = 
    MockRepository.GenerateStub<IQueryable<MyObject>>();

Это не работает, поэтому я попытался сделать это:

IQueryable<MyObject> QueryObject = 
    (new List<MyObject> { new MyObject() }).AsQueryable();

Есть ли лучший способ сделать это или использовать какую-либо другую фальсификацию встроенной поддержки IQueryable?

Мой интерфейс репозитория выглядит следующим образом:

public interface IRepository<T> where T : TableServiceEntity
{
    IQueryable<T> Table { get; }
    void Attach(T existingItem);
    void Delete(T itemToDelete);
    void Insert(T newItem);
    T Load(string partitionKey, string rowKey);
    IEnumerable<T> Load(string partitionKey);
    IEnumerable<T> Query(IQueryable<T> query);
    IEnumerable<T> Last(int count);
    T Last();
    void Update(T item);
}

Вот метод, который я хочу проверить:

public Post LoadPost(int year, int month, int day, string slug)
{
    var query = from p in _blogRepository.Table
                where 
                    p.PartitionKey == Key.Partition(year, month, day) 
                    && p.Slug == slug
                select p;

    var posts = _blogRepository.Query(query.Take(1));

    return posts.First();
}

Тогда вот тест, как я его сейчас, чтобы проверить LoadPost.

[Fact]
public void LoadWillRetrieveByPartitionKeyAndRowKeyWhenUsingUriFormat()
{
    Repository
        .Stub(x => x.Query(Arg<IQueryable<Post>>.Is.Anything))
        .Return(new List<Post> {_post});

    var result = Service.LoadPost(
                            _post.Year(),
                            _post.Month(), 
                            _post.Day(), 
                            _post.Slug);

    Assert.NotNull(result);
}

Код берется из моего проекта AzureBlog.

4b9b3361

Ответ 1

Я обычно делаю то, что вы закончили в своем тесте. При написании тестов я предполагаю, что классы библиотеки .Net работают правильно и не содержат ошибок, поэтому я могу использовать их в тестах. Когда мне нужен тестовый список, сборник, запрос, словарь и т.д. Я просто создаю реальную вещь и заполняю тестовыми данными. Это делает тесты более читабельными и быстрее писать, и, честно говоря, риск не существует.

Ответ 2

Если вы хотите высмеять свой репозиторий, вы не будете издеваться над IQueryable. Вместо этого вымойте методы вашего репозитория, чтобы возвращать фиксированные известные значения (например, ваш второй пример), которые можно использовать для запуска модульных тестов.

Ответ 3

Я знаю, что это старый вопрос, но просто хочу добавить свои 2 цента.

У меня была такая же проблема с репозиториями, сгенерированными с помощью SharpLite, которая является средой ASP.NET MVC, которую я использую время от времени. Через некоторое время я обнаружил решение, единственная проблема - использование Moq, а не Rhino Mocks, но, возможно, вы сможете найти способ его адаптации. Я сделал сообщение в блоге здесь о том, как это сделать.

Он в основном создает список, который реализует IQueryable и использует его как фальшивый фон данных. Надеюсь, что смогу помочь!

Ответ 4

Я не уверен, что это поможет вам... но я сделал что-то вроде того, о чем вы говорите. В моем сценарии у меня был класс контекста данных, который использовал репозиторий.

Я начал с создания интерфейса (IRepository), который включал метод IQueryable. Затем я создал два класса, которые реализуют этот интерфейс. Один класс использует ORM для обработки данных (DbEntityRepository), а другой класс использует свойство класса (MemoryRepository). Класс контекста данных имел конструктор, который требовал IRepository. Для этого я могу использовать MemoryRepository для тестирования контекста данных, и я мог бы использовать DbEntityRepository для приложения.

Если вам интересно... вы можете найти код на codeplex: IQToolkitContrib