Обложка канала

.NET Разработчик

Опытный разработчик не так давно зашёл в .Net и поставил цель получить сертификат Microsoft. Свой ежедневный прогресс он описывает на канале .Net Разработчик. Заметки об изученном материале, советы по повышению производительности и поддержке мотивации, ин

.NET Разработчик

3 года назад
Открыть в
День 1620. #ЗаметкиНаПолях #ЧтоНовенького Время в .NET. Окончание Начало Юнит-Тесты Для тестирования важно иметь возможность имитировать вызов метода объекта с пользовательской реализацией. Поскольку DateTime и DateTimeOffset не имеют интерфейсов, можно создать пользовательскую абстракцию, а затем имитировать её во время тестов. Например, следующий интерфейс может предоставить абстракцию для DateTimeOffset:
public interface ISystemClock
{
  DateTimeOffset UtcNow { get; }
}

Аналогичный подход использовался внутри Microsoft, где один и тот же код был добавлен как минимум в четыре различных области .NET. В .NET 8 были добавлены долгожданные абстракции времени: абстрактный класс TimeProvider и интерфейс ITimer. Они не безупречны, но это значительный прогресс. Недостатки TimeProvider 1. Абстрактный класс получился громоздким. Не зная внутренних деталей класса, зависящего от TimeProvider, невозможно решить, какие его члены надо имитировать: GetUtcNow(), GetLocalNow(), CreateTimer(...) или все сразу. Разработчики предложили разбить новый тип на небольшие интерфейсы, но идея была отвергнута. 2. Экземпляр TimeProvider можно создать с помощью статического члена TimeProvider.System. Его легко использовать, хотя он не сильно отличается от DateTime.Now. В дальнейшем это приведёт к проблемам с написанием юнит-тестов, поэтому ожидается, что разработчики будут внедрять абстрактный TimeProvider в свои классы. Преимущества TimeProvider и ITimer 1. Юнит-тесты сервисов, зависящих от времени, стали более универсальными. TimeProvider был добавлен в BCL и поддерживается в широком спектре сред выполнения .NET. 2. Команда Microsoft исправила в новой реализации старую ошибку, DateTime.Now было ошибочно введено как свойство вместо функции DateTime.Now(), поскольку по рекомендации Microsoft свойства не должны иметь побочных эффектов. TimeProvider правильно использует функции и методы: GetUtcNow(), GetLocalNow(), GetTimestamp() и т. д. 3. Можно тестировать события временных рядов с помощью функций TimeProvider.CreateTimer(...) и Timer.Change(...). Это особенно важно для вызовов функций Task.Delay(...) и Task.WaitAsync(...), которые теперь также принимают аргумент TimeProvider. 4. Планируется создать FakeTimeProvider как часть .NET для дальнейшего упрощения юнит-тестирования. Возможно, тогда пункт 2 из недостатков потеряет актуальность. Стивен Тауб, инженер-программист Microsoft, надеется, что «в будущем почти никто не будет использовать ничего, кроме TimeProvider.System, в производственной среде. В отличие от многих других абстракций, эта особенная: она существует исключительно для возможности тестирования.» Итого Добавление класса TimeProvider в 4м превью .NET 8 определяет стандартизированную и унифицированную абстракцию для управления временем. Хотя он имеет ряд незначительных недостатков, команды Microsoft уже пометили свои интерфейсы времени ISystemClock как устаревшие и теперь выступают за внедрение TimeProvider. Источник: https://www.infoq.com/articles/dotnet-unit-tests-time-timezone/