#Tests fail but code seems to work?

1 messages · Page 1 of 1 (latest)

quick lion
#

I'm possibly doing something very stupid, but I'm wondering if there's any difference in how things get run in a test and when the program itself gets run? I have this test:

[<TestMethod>]
member _.UnixEpoch_CorrectlyDeserializesDateTime () =
    // Arrange
    let expected = DateTime(2024, 9, 27, 0, 0, 0, DateTimeKind.Utc)
    let timestamp = 1727395200000L
    let json = $"""{{"Timestamp":{timestamp}}}"""

    // Act
    let actual = Json.deserializeF<UnixEpochRecord> json

    // Assert
    Assert.AreEqual<DateTime>(expected, actual.Timestamp)

Where these bits are relevant:

module Json =
    let options =
        JsonFSharpOptions()
            .WithUnionUnwrapFieldlessTags()
            .WithSkippableOptionFields(SkippableOptionFields.Always, deserializeNullAsNone = true)
            .ToJsonSerializerOptions()
    
    let deserializeF<'a> (json: string) =
        JsonSerializer.Deserialize<'a>(json, options)

module Converters =
    type UnixEpoch () =
        inherit JsonConverter<DateTime> () with
            override _.Read (reader, typeToConvert, options) =
                DateTimeOffset.FromUnixTimeMilliseconds(reader.GetInt64()).DateTime

            override _.Write (writer, value, options) =
                DateTimeOffset(value).ToUnixTimeMilliseconds() |> writer.WriteNumberValue

type UnixEpochRecord = {
    [<JsonConverter(typeof<Converters.UnixEpoch>)>] Timestamp: DateTime
}

It is supposed to convert some json with a long from a unix timestamp to a DateTime. When I use this when running my program seems to works fine, but when I run the test it fails:

Test method Discordfs.Types.ConvertersTests.UnixEpoch_CorrectlyDeserializesDateTime threw exception: 
System.Text.Json.JsonException: The JSON value could not be converted to System.DateTime. Path: $ | LineNumber: 0 | BytePositionInLine: 13. ---> System.InvalidOperationException: Cannot get the value of a token type 'Number' as a string.

It seems to fail with any use of json serialization, which I'm doing with FSharp.SystemTextJson, since all my other tests that involve it aren't working either. Any ideas what I may have done wrong here?

#

The tests read as if it serialization is not correctly using my JsonFSharpOptions, but I dont see any reason why it wouldnt. The Json and Converters modules are in a separate project which the test project references btw

worthy arch
#

I've seen weird stuff in the past with test runners and module values (such as your options), I think class initializers don't get run so the value ends up null

quick lion
#

if i used an identity function (I think its called, the unit -> JsonSerializerOptions) to set them in my Json.deserializeF would that work around this?

#

seems pretty counterproductive for a test runner to behave differently... honestly i thought it was far more likely I was just doing something silly

worthy arch
#

Yeah making options a function should work

#

I don't know why test runners work like that, it's definitely annoying

quick lion
# worthy arch Yeah making options a function should work

I've been doing some more testing, it still doesnt work when doing that. I've been trying where I call the base JsonSerializer in the test itself, and the test only seems to pass when I dont use JsonFSharpOptions()...ToJsonSerializerOptions(). If I provide nothing or a regular JsonSerializerOptions my test passes

#

but in doing that, more complex objects would fail, since it wouldnt know how to behave for stuff like the DUs and options and whatnot

#

I also tried out without the identity function and it seemed to not be null so i dont think it had that kind of issue either