Moq. Насмешка <T> - как настроить метод, который берет выражение

Я Дразню свой интерфейс репозитория и не уверен, как настроить метод, который берет выражение и возвращает объект? Я использую Moq и NUnit.

Интерфейс:

public interface IReadOnlyRepository : IDisposable
{
    IQueryable<T> All<T>() where T : class;
    T Single<T>(Expression<Func<T, bool>> expression) where T : class;
}

Тест с IQueryable уже настраивается, но не знайте, как настроить Сингл T:

private Moq.Mock<IReadOnlyRepository> _mockRepos;
private AdminController _controller;
[SetUp]
public void SetUp()
{
    var allPages = new List<Page>();
    for (var i = 0; i < 10; i++)
    {
        allPages.Add(new Page { Id = i, Title = "Page Title " + i, Slug = "Page-Title-" + i, Content = "Page " + i + " on page content." });
    }
    _mockRepos = new Moq.Mock<IReadOnlyRepository>();
    _mockRepos.Setup(x => x.All<Page>()).Returns(allPages.AsQueryable());
    //Not sure what to do here???
    _mockRepos.Setup(x => x.Single<Page>()
    //----
    _controller = new AdminController(_mockRepos.Object);
}
29
задан Boann 28 July 2019 в 17:58
поделиться

2 ответа

Пусть вызов .Returns возвращает результат выражения для вашей переменной allPages.

_mockRepos.Setup(x => x.Single<Page>(It.IsAny<Expression<Func<Page, bool>>>()))
    .Returns( (Expression<Func<Page, bool>> predicate) => allPages.Where(predicate) );
8
ответ дан wllmsaccnt 28 November 2019 в 01:30
поделиться

Использование It.IsAny<> Moq без .CallBack вынуждает вас писать код, который не охватывается вашим тестом. Вместо этого он позволяет любому запросу / выражению вообще проходить, делая ваш макет практически бесполезным с точки зрения модульного тестирования.

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

mockPeopleRepository
  .Setup(x => x.Find(ThatHas.AnExpressionFor<Person>()
    .ThatMatches(correctPerson)
    .And().ThatDoesNotMatch(deletedPerson)
    .Build()))
  .Returns(_expectedListOfPeople); 

Вот статья в блоге, в которой говорится об этом и дается исходный код: http://awkwardcoder.com/2013/04/24/ сдерживающими-издевается-с-выражение-аргументы /

1
ответ дан Byron Sommardahl 28 November 2019 в 01:30
поделиться