0

I am working on .NET 5 unit tests for DateTimeUTC. My following tests fails with fraction of millisecond. I am initializing expectedDateTimeUtcNow = DateTimeOffset.UtcNow and then using expectedDateTimeUtcNow to convert to millisecond as SUT to test my method where I pass hardcoded long millisecond value then test pass not sure what I am missing

enter code here

[Fact]
public void ConvertDateTimeToUTC_MustTakeDateTimeParameter_InMilliSecond()
{
        //Arrange
        long startDateTimeUtc = 1626991200000; //2021-07-22 22:00:00
        var expectedDateTime = DateTimeOffset.FromUnixTimeMilliseconds(startDateTimeUtc);

        var expectedDateTimeUtcNow = DateTimeOffset.UtcNow;
        var dateTimeUtcNowMiliSec = expectedDateTimeUtcNow.ToUnixTimeMilliseconds();

        //Act 
        DateTimeOffset utcConvertedDateTime = DateTimeCalculationHelper.ConvertDateTimeToUTC(startDateTimeUtc);
        DateTimeOffset actualDateTimeUtcNow = DateTimeCalculationHelper.ConvertDateTimeToUTC(dateTimeUtcNowMiliSec);


        //Assert
        Assert.Equal(expectedDateTime, utcConvertedDateTime);
        Assert.Equal(expectedDateTimeUtcNow, actualDateTimeUtcNow);
    }

SUT

 public static DateTimeOffset ConvertDateTimeToUTC(long utcDateTimeInMilliSec)
    {
        var dateTimeUtc = DateTimeOffset.FromUnixTimeMilliseconds(utcDateTimeInMilliSec);

        return dateTimeUtc;
    }
K.Z
  • 5,201
  • 25
  • 104
  • 240
  • Can you share code of `DateTimeCalculationHelper.ConvertDateTimeToUTC` ? – Chetan Jul 27 '21 at 15:08
  • I have uploaded code above thanks – K.Z Jul 27 '21 at 15:10
  • Why have you got a `ConvertDateTimeToUTC` method at all? Just inline the call to `DateTimeOffset.FromUnixTimeMilliseconds` everywhere... – Jon Skeet Jul 27 '21 at 15:16
  • i need to moq DateTimeOffset – K.Z Jul 27 '21 at 15:19
  • You really *don't* need to mock DateTimeOffset, and you shouldn't try. You may well want to have a clock interface so that you can control "the current time" but there's nothing in `DateTimeOffset.FromUnixTimeMilliseconds` that needs to be mocked for test purposes. – Jon Skeet Jul 27 '21 at 15:19

2 Answers2

2

Fundamentally, when you convert to a whole number of milliseconds (as you are by calling ToUnixTimeMilliseconds) you lose any sub-millisecond data. This should not be a surprise.

Currently, your test is somewhat like this:

double original = 5.5;
int integer = (int) original;
double result = (double) integer;
Assert.Equal(original, result);

If you understand why that test is bound to fail, just apply the same thing to your situation. You can't "regain" the sub-millisecond information that you lost when you convert back to a DateTimeOffset...

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
0

An alternative but redundant. Test is passed.

 Assert.Equal(expectedDateTimeUtcNow.ToUnixTimeMilliseconds(), actualDateTimeUtcNow.ToUnixTimeMilliseconds()); //PASSED

Ticks are different when compare expectedDateTimeUtcNow vs actualDateTimeUtcNow

Joma
  • 3,520
  • 1
  • 29
  • 32