By default dates and times (DateTime
, DateTimeOffset
, DateOnly
, and TimeOnly
) are sanitized during verification. This is done by finding each date and taking a counter based that that specific date. That counter is then used replace the date values. This allows for repeatable tests when date values are changing.
var dateTime = DateTime.Now;
var dateTimeOffset = DateTimeOffset.Now;
var target = new DateTimeTarget
{
DateTime = dateTime,
Date = new(dateTime.Year, dateTime.Month, dateTime.Day),
DateNullable = new(dateTime.Year, dateTime.Month, dateTime.Day),
DateString = new Date(dateTime.Year, dateTime.Month, dateTime.Day).ToString(),
DateTimeNullable = dateTime,
DateTimeString = dateTime.ToString("F"),
DateTimeOffset = dateTimeOffset,
DateTimeOffsetNullable = dateTimeOffset,
DateTimeOffsetString = dateTimeOffset.ToString("F")
};
await Verify(target);
Results in the following:
{
DateTime: DateTime_1,
DateTimeNullable: DateTime_1,
Date: Date_1,
DateNullable: Date_1,
DateTimeOffset: DateTimeOffset_1,
DateTimeOffsetNullable: DateTimeOffset_1,
DateTimeString: DateTimeOffset_2,
DateTimeOffsetString: DateTimeOffset_2,
DateString: Date_1
}
To disable this behavior use:
var target = new
{
Date = new DateTime(2020, 10, 10, 0, 0, 0, DateTimeKind.Utc)
};
var settings = new VerifySettings();
settings.DontScrubDateTimes();
return Verify(target, settings);
var target = new
{
Date = new DateTime(2020, 10, 10, 0, 0, 0, DateTimeKind.Utc)
};
return Verify(target)
.DontScrubDateTimes();
[ModuleInitializer]
public static void ModuleInitializer() =>
VerifierSettings.DontScrubDateTimes();
If many calls are made to the current date/time in quick succession, the date counting behavior (DateTime_x
) can result in inconsistent results. To revert to the simpler scrubbing convention ({Scrubbed}
) use DisableDateCounting.
var target = new
{
Date = new DateTime(2020, 10, 10, 0, 0, 0, DateTimeKind.Utc)
};
var settings = new VerifySettings();
settings.DisableDateCounting();
return Verify(target, settings);
var target = new
{
Date = new DateTime(2020, 10, 10, 0, 0, 0, DateTimeKind.Utc)
};
return Verify(target)
.DisableDateCounting();
[ModuleInitializer]
public static void ModuleInitializer() =>
VerifierSettings.DisableDateCounting();
AddExtraDateTimeFormat
allows specifying custom date formats to be scrubbed.
[ModuleInitializer]
public static void UseAddExtraDateTimeFormat() =>
VerifierSettings.AddExtraDateTimeFormat("yyyy-MM-dd");
[Fact]
public Task WithExtraDateTimeFormat() =>
Verify(
new
{
date = "2022-11-08"
});
Strings containing inline dates can also be scrubbed. There a equivalent APIs for DateOnly
, DateTime
, and DateTimeOffset
.
[Fact]
public Task ScrubInlineDateTimesInstance()
{
var settings = new VerifySettings();
settings.ScrubInlineDateTimes("yyyy-MM-dd");
return Verify(
"content 2020-10-20 content",
settings);
}
[Fact]
public Task ScrubInlineDateTimesFluent() =>
Verify("content 2020-10-20 content")
.ScrubInlineDateTimes("yyyy-MM-dd");
public static class ModuleInitializer
{
[ModuleInitializer]
public static void Init() =>
VerifierSettings.ScrubInlineDateTimes("yyyy-MM-dd");
}
Specific date or times can be named. When any of those values are found, they will be matched with the corresponding name.
var settings = new VerifySettings();
settings.AddNamedDate(new(2020, 10, 11), "instanceNamedDate");
settings.AddNamedTime(new(1, 2), "instanceTime");
settings.AddNamedDateTime(new(2030, 1, 2), "instanceNamedDateTime");
settings.AddNamedDateTimeOffset(new DateTime(2030, 1, 2), "instanceNamedTimeOffset");
await Verify(target, settings);
await Verify(target)
.AddNamedDate(new(2020, 10, 11), "instanceNamedDate")
.AddNamedTime(new(1, 2), "instanceTime")
.AddNamedDateTime(new(2030, 1, 2), "instanceNamedDateTime")
.AddNamedDateTimeOffset(new DateTime(2030, 1, 2), "instanceNamedTimeOffset");
[ModuleInitializer]
public static void NamedDatesAndTimesGlobal()
{
VerifierSettings.AddNamedDateTime(new(2030, 1, 1), "namedDateTime");
VerifierSettings.AddNamedTime(new(1, 1), "namedTime");
VerifierSettings.AddNamedDate(new(2030, 1, 1), "namedDate");
VerifierSettings.AddNamedDateTimeOffset(new(new(2030, 1, 1)), "namedDateTimeOffset");
}
The following comparers can be overridden
Default Comparer:
class DateTimeComparer : IEqualityComparer<DateTime>
{
public bool Equals(DateTime x, DateTime y) =>
x == y &&
x.Kind == y.Kind;
public int GetHashCode(DateTime obj) =>
obj.GetHashCode() + (int) obj.Kind;
}
Custom Comparer:
[ModuleInitializer]
public static void UseCustomDateTimeComparer() =>
Counter.UseDateTimeComparer(new CustomDateTimeComparer());
public class CustomDateTimeComparer :
IEqualityComparer<DateTime>
{
public bool Equals(DateTime x, DateTime y) =>
new DateTime(x.Year, x.Month, x.Day) ==
new DateTime(y.Year, y.Month, y.Day);
public int GetHashCode(DateTime date) =>
new DateTime(date.Year, date.Month, date.Day).GetHashCode();
}
Default Comparer:
class DateTimeOffsetComparer :
IEqualityComparer<DateTimeOffset>
{
public bool Equals(DateTimeOffset x, DateTimeOffset y) =>
x == y && x.Offset == y.Offset;
public int GetHashCode(DateTimeOffset obj) =>
obj.GetHashCode() + (int) obj.Offset.TotalMinutes;
}
Custom Comparer:
[ModuleInitializer]
public static void UseCustomDateTimeOffsetComparer() =>
Counter.UseDateTimeOffsetComparer(new CustomDateTimeOffsetComparer());
public class CustomDateTimeOffsetComparer :
IEqualityComparer<DateTimeOffset>
{
public bool Equals(DateTimeOffset x, DateTimeOffset y) =>
new DateTimeOffset(new(x.Year, x.Month, x.Day)) ==
new DateTimeOffset(new(y.Year, y.Month, y.Day));
public int GetHashCode(DateTimeOffset date)
{
var dateTime = new DateTime(date.Year, date.Month, date.Day);
return new DateTimeOffset(dateTime)
.GetHashCode();
}
}
Default Comparer:
EqualityComparer<Time>.Default;
Custom Comparer:
[ModuleInitializer]
public static void UseCustomTimeComparer() =>
Counter.UseTimeComparer(new CustomTimeComparer());
public class CustomTimeComparer :
IEqualityComparer<Time>
{
public bool Equals(Time x, Time y) =>
new Time(x.Hour, x.Minute, x.Second) ==
new Time(y.Hour, y.Minute, y.Second);
public int GetHashCode(Time date) =>
new Time(date.Hour, date.Minute, date.Second).GetHashCode();
}