Как выполнить модульное тестирование выражения, передаваемого в слой хранилища - PullRequest
0 голосов
/ 18 мая 2018

У меня есть сервисный уровень, который вызывает уровень репозитория для извлечения данных, а затем работает с возвращаемым объектом.Я хочу проверить выражение, отправляемое в репозиторий методом «get», скажем, в случае, если первичный ключ становится составным ключом или чем-то подобным.

Пример:

public async Task ArchiveAsync(Domain.Person person)
{
    Data.Person entityModel = await _repo.SingleOrDefaultAsync<Data.Person>(p => p.Id == person.Id);

    // Stuff is done here...
}

Итак, в этомНапример, объект домена передается, объект данных извлекается, и с ним что-то делается.Я хочу проверить выражение, передаваемое в метод SingleOrDefaultAsync.

Мысли?

Ответы [ 2 ]

0 голосов
/ 21 мая 2018

Вероятно, лучше реорганизовать ваш код и сделать "выражение" правильной сущностью.Шаблон Спецификация идеально подходит для вашего случая.

Владимир Хориков написал большую простую статью об этом: Шаблон спецификации: реализация C #

У него есть пример проекта, опубликованного на GitHub здесь

В случае, если ссылка станет недействительной, я добавлю здесь основную логику ядра.
Ваш репозиторий будет выглядеть следующим образом:

public IReadOnlyList<T> Find(Specification<T> specification)
{
        using (context))
        {
            return context.DbSet<T>()
                .Where(specification.ToExpression())
                .ToList();
        }
}

Для класса Спецификации вы можете найти много реализаций.
Это небольшой служебный класс, который в конечном итоге преобразуется в выражение

Если вы разрабатываете свое приложение таким образом, вы можете легко проверить свою Спецификацию (что практически ваше выражение)

0 голосов
/ 20 мая 2018

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

Вместо репозитория потребуется предоставить макет, вы можете использовать любую библиотеку, какую пожелаете. Moq или NSubstitute в качестве примера.

Затем вы должны получить Expression<Func<Domain.Person, bool>> объект, переданный в ваш репозиторий при вызове SingleOrDefaultAsync.Это должно быть довольно просто с большинством насмешливых библиотек.

И, наконец, вам нужно скомпилировать ваше выражение в Func<Domain.Person, bool> и утверждать, что оно возвращает true для Domain.Person объекта с ожидаемым Idи false в противном случае.

И небольшой снимок, чтобы проиллюстрировать, я предполагаю, что здесь есть только один аргумент, это единственный вызов для объекта репозитория и что Domain.Person.Id имеет открытый сеттер.

var repository = Substitute.For<IRepository>();
var service = new Service(repository);
var person = new Domain.Person { Id = 42 };

await service.ArchiveAsync(person);

var call = repository.ReceivedCalls().First();
var arg = call.GetArguments().First();
var expr = (Expression<Func<Domain.Person, bool>>)arg;
var func = expr.Compile();

Assert.True(func(person));
Assert.False(func(new Domain.Person {Id = 1}));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...