TGViewer
.NET Разработчик .NET Разработчик @netdeveloperdiary · 6.77K subscribers
Post #1969 1.57K
День 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/
  • 👍 7
More from @netdeveloperdiary
  1. Oct 10, 2026День 2810. #ЧтоНовенького #VSCode Более Быстрый и Лёгкий C# Dev Kit Мы, разработчики, люби…
  2. Oct 9, 2026День 2809. #Карьера 5 Навыков, Которые Помогут Быстрее Стать Сеньором. Окончание Начало 3.…
  3. Oct 8, 2026День 2808. #Карьера 5 Навыков, Которые Помогут Быстрее Стать Сеньором. Начало В ИТ есть се…
  4. Oct 7, 2026День 2807. #ЗаметкиНаПолях Типы Коллекций в .NET, Которые Стоит Попробовать. Окончание Нач…
  5. Oct 6, 2026🦈 Открытое собеседование на Middle C# | 6 октября, 19:00 МСК Приглашаем на открытое собес…
  6. Oct 6, 2026День 2806. #ЗаметкиНаПолях Типы Коллекций в .NET, Которые Стоит Попробовать. Начало Больши…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →