Quantcast
Channel: C#タグが付けられた新着記事 - Qiita
Viewing all articles
Browse latest Browse all 9711

C# と SQL Server の DateTime を Assert.Equals する

$
0
0

C# と Database ではそれぞれミリ秒の保持の仕方が異なります。上手く Assert するには比較用のクラスを作って、 Assert の Parameter に渡してあげれば OK です。

使っているもの

  • xUnit
  • SQL Server

なぜ起きるのか

C# の DateTime ではミリ秒を正しく保持しています。

C#: 2013-05-01 23:59:59.991

しかし、これを SQL Server の datetime に入れるとこうなります。

SQL Server: 2013-05-01 23:59:59.990

これには理由があって、ミリ秒の精度が .000、.003、.007 であるためです。よって、このまま Assert.Equals すると Fail してしまいます。

解決方法

比較用のクラスをパラメーターで渡してあげて、多少の時間を許容するようにします。

Assert.Equal(expected,actual,newSqlServerDateTimeComparer());

比較用のクラス

いくつか用意してあるので合ったものを使ってください。また、このクラスでは 10 秒までの差は許容しているので、この設定値は Constructor で受け取れるようにするなどすれば、別の比較 (e.g. DateTime が DI 出来なくて死ぬ Unit Test など) にも使えると思います。

publicclassSqlServerNullableDateTimeComparer:IEqualityComparer<DateTime?>{publicboolEquals(DateTime?x,DateTime?y){if(x==null&&y==null){returntrue;}if(x==null||y==null){returnfalse;}return(x.Value-y.Value).Duration()<TimeSpan.FromSeconds(10);}publicintGetHashCode(DateTime?obj){returnobj.GetHashCode();}}publicclassSqlServerDateTimeComparer:IEqualityComparer<DateTime>{publicboolEquals(DateTimex,DateTimey){return(x-y).Duration()<TimeSpan.FromSeconds(10);}publicintGetHashCode(DateTimeobj){returnobj.GetHashCode();}}publicclassSqlServerNullableDateTimeOffsetComparer:IEqualityComparer<DateTimeOffset?>{publicboolEquals(DateTimeOffset?x,DateTimeOffset?y){if(x==null&&y==null){returntrue;}if(x==null||y==null){returnfalse;}return(x.Value-y.Value).Duration()<TimeSpan.FromSeconds(10);}publicintGetHashCode(DateTimeOffset?obj){returnobj.GetHashCode();}}publicclassSqlServerDateTimeOffsetComparer:IEqualityComparer<DateTimeOffset>{publicboolEquals(DateTimeOffsetx,DateTimeOffsety){return(x-y).Duration()<TimeSpan.FromSeconds(10);}publicintGetHashCode(DateTimeOffsetobj){returnobj.GetHashCode();}}

Note

DATETIME データ型のミリ秒に関する注意事項 – Microsoft SQL Server Japan Support Team Blog


Viewing all articles
Browse latest Browse all 9711

Trending Articles