New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support assertions on System.Text.Json.JsonSerializerOptions based (de)serialization #2246
base: develop
Are you sure you want to change the base?
Conversation
e2be3c9
to
b193be3
Compare
51a90ec
to
3bcbc37
Compare
Qodana for .NET16 new problems were found
💡 Qodana analysis was run in the pull request mode: only the changed files were checked Contact Qodana teamContact us at qodana-support@jetbrains.com
|
3bcbc37
to
a1b4023
Compare
Added |
ade53f1
to
bb67152
Compare
/// <param name="becauseArgs"> | ||
/// Zero or more objects to format using the placeholders in <see paramref="because" />. | ||
/// </param> | ||
public AndConstraint<JsonElementAssertions> BeString(string value, string because = "", params object[] becauseArgs) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not use Be()
in every case? The type info on the method name is redundant.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I considered that, and if we would only assert on simple nodes, that might would be sufficient.
However, if the JSON is a complex structure, you might want to assert against the JSON string it results in, what is different then the a JSON string node/element. Besides that, it also makes implicit that both the value and the element type are asserted.
In general, what the API should look like for JSON array, and JSON object results, is something I'm still thinking about. I think I personally would use this to assert on the full JSON result as a string:
options.Should().Serialize(myComplexModel)
And.Shoud().Be("{ 'prop': 'Value', 'other': 12, children: [ ]}");
but others might opt for:
options.Should().Serialize(myComplexModel)
And.Shoud().Be(new()
{
prop = "Value" ,
other = 12,
children = Array.Empty<object>()
});
Where the anonymous object is used to represent the JsonElement
. The latter is normally used for BeEquivalent()
, but I'm wondering if that has meaning for this kind of assertions.
I'm also wondering if we want the opposite of BeString()
, etc. Because, what does that say? That I except something not to be a string? Or a string, but with a different value?!
Thanks for taking the lead to spike out the implementation. I still have doubts though. Consider this example from the PR. options.Should().Serialize("42").And.Value.Should().BeNumber(42, because: "why not?"); I have two issues with this:
To make it more idiomatic FA, it could look like this: "42".Should().BeSerializableToJson(options).Which.Value().Should().BeNumber(42, because: "why not?"); |
For me, there are two types of (de)serialization tests I'd like to write: when a custom type that is decorated with custom The other kind of test, is about the |
bb67152
to
667dd63
Compare
Qodana for .NET10 new problems were found
💡 Qodana analysis was run in the pull request mode: only the changed files were checked Contact Qodana teamContact us at qodana-support@jetbrains.com
|
@dennisdoomen About |
667dd63
to
7dd7080
Compare
3> The other kind of test, is about the I'm sorry, but I disagree.
I think so, just like |
That is also true. Unfortunately, the JSON Serializer of System.Text.Json is a static method. It are these options that define its behavior, and you want to test if those the setup of your serializer will result in the kind of serialization you like. (With System.Text.Json, you could actually resolve a serializer with - in that case settings - to have something like: in outer words: I would like to be able to say: If I want to specify that because of my JsonOptions, null properties are ignored, it is not about the object that is serialized, but about that it is configured that way (in the options). So to me: options.Should().Serialize().Which.Value().Should().Be("{}"); Is then better than: new { Name = (string) null }.Should().BeJsonSerializable(options).Which.Value().Should().Be("{}"); I've thought of another name than
Than I'll add that one. |
What's wrong with this one? There's a subject-under-test, there are the |
@dennisdoomen About |
An important part of JSON (de)serialization specifications, is defining the intended behavior of it. This (draft) PR an attempt to create a readable/maintainable/extendable syntax, that fits within FluentAssertions.
IMPORTANT
./build.sh --target spellcheck
or.\build.ps1 --target spellcheck
before pushing and check the good outcomeSee: #2205