【JUnit】【トラブル】 MySQL利用でAssertJ-DB を使った単体テストを行ったら日時でエラーになる

現象

 * MySQLを利用したシステムで、AssertJ-DB を使った単体テストを行ったら
   日時でエラーになってしまう

単体試験内容

Calendar targetDate = Calendar.getInstance();
int result = TargetSample3.insert("X0001", "Apple", 129, targetDate);
// 略
assertThat(table).row(0).value("releasedate").isEqualTo(new DateTimeValue(targetDate));
元ネタは以下の関連記事を参照
http://blogs.yahoo.co.jp/dk521123/36164701.html

エラー内容

Expecting:
  <2016-06-21T22:41:05.000000000>
to be equal to: 
  <2016-06-21T22:41:04.866000000>

原因

http://qiita.com/kamipo/items/fb3f7aff8e08fcd67898
より抜粋

MySQL 5.6からDATETIMEは小数点以下が四捨五入(round)される
対して、DateTimeValueはミリ秒まで設定するので不一致となり、エラーと判断されてしまう
https://github.com/joel-costigliola/assertj-db/blob/master/src/main/java/org/assertj/db/type/TimeValue.java
より抜粋

public TimeValue(Calendar calendar) {
    if (calendar == null) {
      throw new NullPointerException("time should be not null");
    }

    hours = calendar.get(Calendar.HOUR_OF_DAY);
    minutes = calendar.get(Calendar.MINUTE);
    seconds = calendar.get(Calendar.SECOND);
    nanoSeconds = calendar.get(Calendar.MILLISECOND) * 1000000;
  }

対策案

 * 期待値をミリ秒を四捨五入して比較する

修正案

http://stackoverflow.com/questions/20385067/how-to-round-off-timestamp-in-milliseconds-to-nearest-seconds
を参考に修正。

assertThat(table).row(0).value("releasedate").isEqualTo(toDateTimeValue(targetDate));

// 略

// ミリ秒を四捨五入
private static DateTimeValue toDateTimeValue(Calendar targetDateTime) {
  DateValue dateValue = new DateValue(targetDateTime);
  int hour = targetDateTime.get(Calendar.HOUR_OF_DAY);
  int minute = targetDateTime.get(Calendar.MINUTE);
  int second = targetDateTime.get(Calendar.SECOND);
  int milliSecond = targetDateTime.get(Calendar.MILLISECOND);

  // For MySQL
  second = second + ((milliSecond + 500) / 1000);

  TimeValue timeValue = new TimeValue(hour, minute, second);
  return new DateTimeValue(dateValue, timeValue);
}

関連記事

DBにまつわる単体試験 [3] ~ AssertJ / AssertJ-DB ~

http://blogs.yahoo.co.jp/dk521123/36157721.html

AssertJ / AssertJ-DB ~ 日付 / 時間 / 日時 について ~

http://blogs.yahoo.co.jp/dk521123/36164701.html