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?

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

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

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

Войти через центр авторизации
Похожие вопросы