You can consider time as a dependency and inject it into your method. I suggest using the IClock
interface from the NodaTime. Then in your unit tests, you can use the FakeClock
class from NodaTime.Testing.
Your modified method.
public static int GetAge(IClock clock, DateTime birthdate)
{
now = clock.GetCurrentInstant().ToDateTimeUtc();
// use now and birthdate to calculate age
}
Then you can write your unit test like this.
[TestMethod]
public void GetAgeTest()
{
var clock = new FakeClock(Instant.FromUtc(2013, 1, 1, 0, 0, 0)); // Create a fake clock that always return 2013/01/01 0:00:00
var birthDate = new DateTime(2000, 1, 1, 0, 0, 0, DateTimeKind.Utc);
Assert.AreEqual(GetAge(clock, birthdate), 13); Always return 13
}
If you ever decide to move GetAge
into its own class.
public class AClass
{
private readonly IClock _clock;
public AClass(IClock clock) => _clock = clock;
public int GetAge(DateTime birthdate)
{
now = _clock.GetCurrentInstant().ToDateTimeUtc();
// use now and birthdate to calculate age
}
}
The FakeClock
is a very powerful testing tool. You can read more about it from my blog post here.