Luffy1
@Luffy1
Student, Junior .NET programmer, C#, JS, HTML/CSS

Как сделать Mock на приватное поле типа Dictionary для Integration tests или как можно проверить, что его метод был вызван?

Я делаю проект на WPF, используя MVVM подход. У меня есть так званый "мост" между репозиторием и ViewModel, который во ViewModel из репки подгружает нужные данные, - DataProvider. Это сделано для будущей имплементации кэша. Но щас не об этом. Вот собственно этот класс:
public class RatingRecordProvider : IRatingRecordProvider, IDisposable
{
    private IReadAllRepository<RatingRecord, DifficultyLevels> _dataService;
    private Dictionary<DifficultyLevels, IEnumerable<RatingRecord>> _cache; // temporary improvisation of cache, lmao
                                                                            // in the future, it's planned that cache here is cleaned every 5 min.

    public RatingRecordProvider(IReadAllRepository<RatingRecord, DifficultyLevels> dataService)
    {
        _dataService = dataService;
        _cache = new Dictionary<DifficultyLevels, IEnumerable<RatingRecord>>();
    }

    // Too inefficient an operation. This is a temporary solution until a proper cache service is implemented.
    // MVP, anyway.
    public void Add(RatingRecord entity, DifficultyLevels key)
    {
        _dataService.Add(entity, key);
        var newRatingRecords = _dataService.GetAll(key);

        if (IsKeyInCache(key))
            _cache.Remove(key);

        _cache.Add(key, newRatingRecords);
    }

    public IEnumerable<RatingRecord> GetAll(DifficultyLevels key)
    {
        var ratingRecords = _cache[key];
        if (ratingRecords == null)
        {
            ratingRecords = _dataService.GetAll(key);
            _cache.Add(key, ratingRecords);
        }
        return ratingRecords;
    }

    public void Dispose()
    {
        _cache.Clear(); // Honestly, I'm not sure if it's needed or not. Let it be here for some time.
    }

    private bool IsKeyInCache(DifficultyLevels key) => _cache.Count(pair => pair.Key == key) != 0;
}


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

Итак, мне нужно написать для этого класса интеграционные тесты. Для этого мне нужно проверять, был ли вызван метод Add этого Dictionary. Если б этот кэш представлял отдельный класс, который имеет интерфейс и т п, то я бы сделал мок и с помощью Verify проверял бы. Но я в данный момент реализую кэш с помощью просто контейнера.

Допустим, можно как-то сделать мок на Dictionary. Окей. Но мы ведь не передаём кэш через конструктор! И я считаю, что он и не должен передаваться, что у него зона действия должна быть только внутри класса и создаваться он должен только внутри класса.

Или я не прав? И его стоит, нужно и лучше передавать через параметры? Или лучше реально потратить больше времени и сделать отдельные класс и интерфейс, но зато потом легко писать тесты?

Или может быть есть решение какое-то для именно имплементации кэша в виде private Dictionary?

У меня опыта в разработке через тесты пока что мало... Любая идея будет полезной! Заранее благодарю=)
  • Вопрос задан
  • 76 просмотров
Решения вопроса 1
@mvv-rus
Настоящий админ AD и ненастоящий программист
Сделайте фабрику для экземпляра, реализующего кэш, и передавайте через конструктор её, в виде интерфейса. Тогда кэш у вас будет частным, действующим только внутри класса, но конкретная его реализация будет задаватьс снаружи. И все будет по фэн-шуюSOLID
Для теста передайте в конструктор имитатор ("мок") этой фабрики, который создает и возвращаетнужный вам имитатор кэша.

PS Стндартная для .NET имплементация кэша в памяти - это MemoryCache, он реализует интерфейс IMemoryCache. Только вот самому его имитировать нетривиально, поскольку у него есть особенность в поведении: его элемент (ICacheEntry) сохраняется в кэше по факту очистки (вызову Dispose() ). Я про это даже статью на Хабре написал.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы
Bip.ru Москва
от 150 000 до 250 000 ₽
Альфа-Банк Москва
от 200 000 ₽
Bip.ru Москва
от 250 000 до 350 000 ₽
08 окт. 2024, в 17:08
10000 руб./за проект
08 окт. 2024, в 17:01
15000 руб./за проект