WireMock-Net / WireMock.Net

WireMock.Net is a flexible product for stubbing and mocking web HTTP responses using advanced request matching and response templating. Based on the functionality from http://WireMock.org, but extended with more functionality.
Apache License 2.0
1.35k stars 197 forks source link

How to force a formatted DateTime to return a string? #1028

Closed felipetofoli closed 6 months ago

felipetofoli commented 7 months ago

First of all, thanks for this amazing lib! :)

I have to apply a specific format ("yyMMddhhmmss") to a DateTime and receive a string as the result. I tried multiple approaches, but I always receive an integer, instead of a string. So my question is: How to force a formatted DateTime to return a string?

Example:

"BodyAsJson": {
    "timestamp": "{{ DateTime.UtcNow \"yyMMddhhmmss\" }}",
    "timestamp2": "{{ DynamicLinq.Expression 'DateTime.UtcNow.ToString(\"yyMMddhhmmss\")' }}",
    "timestamp3": "{{ String.Format (DateTime.UtcNow) \"yyMMddhhmmss\" }}",
}

The above JSON configuration returns the following result:

{
    "timestamp": 231205110312,
    "timestamp2": 231205110312,
    "timestamp3": 231205110312
}

The expected/desired result:

{
    "timestamp": "231205110312",
    "timestamp2": "231205110312",
    "timestamp3": "231205110312"
}

I already tried wrapping the configuration with double quotes, using String.Append to append an empty string (""), but I wasn't able to get the expected/desired result.

Please let me know if any other information is needed! Thanks!

StefH commented 6 months ago

@felipetofoli This looks the same as this issue: https://github.com/WireMock-Net/WireMock.Net/issues/884

I think the only solution for you would be not to use BodyAsJson, but just Body and return the required json message as a string.

Like:

"{\n    \"timestamp\": \"{{ DateTime.UtcNow \\\"yyMMddhhmmss\\\" }}\",\n    \"timestamp2\": \"{{ DynamicLinq.Expression 'DateTime.UtcNow.ToString(\\\"yyMMddhhmmss\\\")' }}\",\n    \"timestamp3\": \"{{ String.Format (DateTime.UtcNow) \\\"yyMMddhhmmss\\\" }}\",\n}"
StefH commented 6 months ago

https://github.com/WireMock-Net/WireMock.Net/pull/1029

StefH commented 6 months ago

@felipetofoli is this ok for you?

felipetofoli commented 6 months ago

Hi @StefH ! Thanks for the response!

Yes, the Body approach works for the JSON configuration.

I am thinking about using C# mappings instead (to avoid the inline configurations).

According to the other issues, the .WithTransformer(ReplaceNodeOptions.EvaluateAndTryToConvert) should do the trick, right? Reference: https://github.com/WireMock-Net/WireMock.Net/issues/884#issuecomment-1693548031

Or should I use .WithTransformer(ReplaceNodeOptions.KeepString)? Reference: https://github.com/WireMock-Net/WireMock.Net/issues/884#issuecomment-1432874211

StefH commented 6 months ago

I'm not 100% sure anymore if that enim option works as intended

So for now use c# mappings or a body as string.

felipetofoli commented 6 months ago

@StefH, I've just tested the c# mappings, but they are returning a number either - instead of a string:

server
    .Given(Request
        .Create()
        .WithPath(new ExactMatcher("/datetime-test"))
        .UsingPost())
    .RespondWith(Response
        .Create()
        .WithHeader("Content-Type", "application/json")
        .WithBodyAsJson(new
        {
            timestamp = "{{ DateTime.UtcNow \"yyMMddhhmmss\" }}",
        })
        .WithTransformer());

Response:

{"timestamp":231207053817}

Is there any other configuration to do?

Thanks,

StefH commented 6 months ago

Sorry. In that case : use a string instead of json.

I need to think in how to change the internal logic.