kulifmor.com

Bending DateTime in .NET for Improved Code Testing

Written on

Chapter 1: Introduction to DateTime Mocking

Mocking DateTime in .NET can be quite challenging. However, there's a more efficient way to manage it.

As a seasoned engineer, I've faced the issue of having to deal with DateTime.Now or DateTime.UtcNow in my code. When I write tests, validating the exact time can be problematic due to the milliseconds that elapse between executing the code and performing the check. While this may seem trivial, it can be quite bothersome, especially since I prefer to ensure the accuracy of every aspect of my code.

Fortunately, there's a straightforward solution to this dilemma. Before diving into the details, I want to extend my gratitude to Andrew Harcourt, Andrew Wickens, and Jared Wilton for their invaluable encouragement.

To summarize, you can utilize my SimpleDateTimeProvider NuGet package to effectively address this issue. Below, you'll find the implementation details.

The Solution

I've developed a DateTimeProvider that consists of an interface along with two distinct implementations. One implementation returns the actual system values, while the other provides mocked values that users can set as needed.

Interface Definition

public interface IDateTimeProvider

{

DateTime Now { get; }

DateTime Today { get; }

DateTime UtcNow { get; }

}

System Implementation

public class SystemDateTimeProvider : IDateTimeProvider

{

public DateTime Now => DateTime.Now;

public DateTime Today => DateTime.Today;

public DateTime UtcNow => DateTime.UtcNow;

}

Mock Implementation

public class MockDateTimeProvider : IDateTimeProvider

{

public DateTime Now

{

get => this.now.ThrowIfNotSet(DateTimeType.Now);

set => this.now = value;

}

public DateTime Today

{

get => this.today.ThrowIfNotSet(DateTimeType.Today);

set => this.today = value;

}

public DateTime UtcNow

{

get => this.utcNow.ThrowIfNotSet(DateTimeType.UtcNow);

set => this.utcNow = value;

}

}

Using the DateTime Providers

This approach is straightforward. You can easily implement the system provider under the IDateTimeProvider interface in your functional code. If you're familiar with dependency injection libraries, you’ll find the syntax intuitive—just follow the established pattern.

builder.Services.AddSingleton<IDateTimeProvider, SystemDateTimeProvider>();

Next, create your service class and employ the registered SystemDateTimeProvider through the IDateTimeProvider interface. You can then use the provider to set DateTime values within your class.

public class Service

{

private readonly IDateTimeProvider dateTimeProvider;

public Service(IDateTimeProvider dateTimeProvider)

{

this.dateTimeProvider = dateTimeProvider;

}

public string DateTimeNow()

{

return $"DateTime.Now is {this.dateTimeProvider.Now}";

}

}

The core objective of this implementation is to facilitate testable code. Now, with the class defined above, you can substitute in the MockDateTimeProvider for testing purposes, allowing for controlled DateTime values.

Testing Example

The following example illustrates how to create a test using XUnit, along with Shouldly for assertions.

[Fact]

public void Today_ShouldReturn_MockedToday()

{

// Arrange

var provider = new MockDateTimeProvider();

var service = new Service(provider);

var today = DateTime.Today;

provider.Today = today;

// Act

var result = service.DateTimeToday();

// Assert

_ = result.ShouldBeOfType<string>();

result.ShouldBe($"DateTime.Today is {today}");

}

Where to Find This

All of this is open-sourced. You can explore my work on GitHub at the SimpleDateTimeProvider repository and find the NuGet package there as well.

Connect and Support

If you find this information helpful or want to check out my other projects, please connect with me on LinkedIn or GitHub. Your support is always appreciated, and I welcome any contributions, even if it’s just $1 on GitHub Sponsors or Buy Me a Coffee.

Chapter 2: Enhanced DateTime Handling

In this video, titled "The RIGHT way to deal with Date and Time in C#," you'll discover best practices for managing DateTime in C# applications.

Additionally, check out the video "C# Tutorial - How to create line chart | FoxLearn," which provides insights on implementing line charts in your applications.

Share the page:

Twitter Facebook Reddit LinkIn

-----------------------

Recent Post:

Exploring Mike's Favorite Stories on ILLUMINATION Publications

Discover Mike's curated collection of impactful stories highlighting health, science, and community engagement.

Tesla's Model 2: A Game-Changer or Just Another EV?

An in-depth look at Tesla's Model 2, its potential advantages, and competition in the affordable EV market.

Becoming an AI Product Manager: The Essential Guide

Explore the distinctions between AI product managers and traditional PMs, and how AI influences product management.

Understanding Git: A Comprehensive Guide for Team Collaboration

Explore Git and its role in collaborative coding, distinguishing it from other software, and learn how to utilize it effectively.

Eat Up: Celebrating the Joy of Red Meat

A tribute to red meat and its nutritional benefits, inviting creative responses and reflections on meat-eating experiences.

# The Complex Relationship Between Alcohol and Brain Health

A humorous take on the conflicting studies surrounding alcohol consumption and brain health.

Rise Above: Embracing Our True Potential and Freedom

Discover how to break free from mental limitations and embrace your true potential.

Recognizing the Right Time to Change Your Career Path

Discover key indicators that signal it's time for a career change, based on personal experiences and insights.