Skip to content

Added ShouldBeJsonSerializable#52

Merged
dennisdoomen merged 6 commits intofluentassertions:masterfrom
rikrak:ShouldBeJsonSerializable
Apr 29, 2021
Merged

Added ShouldBeJsonSerializable#52
dennisdoomen merged 6 commits intofluentassertions:masterfrom
rikrak:ShouldBeJsonSerializable

Conversation

@rikrak
Copy link
Copy Markdown
Contributor

@rikrak rikrak commented Apr 28, 2021

Added ShouldBeJsonSerializable (see #3 )
Note: I've added the extension to the root namespace (FluentAssertions) to aid discovery.

This is based on a previous PR[1] by @borismod that was never merged

[1] 54432fd

Copy link
Copy Markdown
Member

@dennisdoomen dennisdoomen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Apologies, but I noticed I wasn't finished with the review.

{
var serializedObject = JsonConvert.SerializeObject(subject);
var cloneUsingJsonSerializer = JsonConvert.DeserializeObject(serializedObject, subject.GetType());
return cloneUsingJsonSerializer; ;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🙃 Nitpick: unnecessary semi-colon

.IncludingFields()
.IncludingProperties();

var typedSubject = (T)assertions.Subject;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤔 What if the subject is not of type T?
🤔 What if the subject is null?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With respect to what to do if the subject is null: Both BeBinarySerializable() and BeDataContractSerializable() fail the assertion with what looks like a NullReferenceException. I could do the same, but I was thinking of something more like this:

    Execute.Assertion.ForCondition(assertions.Subject != null)
        .BecauseOf(because, becauseArgs)
        .FailWith("Expected {object:context} to be JSON serializable{reason}, but the value is null.  Please provide a value for the assertion.");

Not quite sure on the fail message, but it gets the point across I think

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, that's sloppy old code. The main library will do exactly what you suggested.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done :-)

Action act = () => target.Should().BeJsonSerializable();

// assert
act.Should().Throw<Xunit.Sdk.XunitException>();
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤔 I think we should also verify a part of the message to make sure the test fails for the right reasons. Same for the other tests where you expect an exception.

}

[Fact]
public void Class_is_simple_poco_should_be_serializable()
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤔 I don't quite get this naming convention in all of these test cases. For this one, did you intend to say "Class as simple poco should be serializable"? Maybe "Simple_poco_should_be_serializable" or "When_class_is_simple_poco_it_should_be_serializable"?

@rikrak
Copy link
Copy Markdown
Contributor Author

rikrak commented Apr 29, 2021

I'm not too familiar with the etiquette of github - Should I mark the review comments as Resolved after a commit, or is that up to the reviewer? Either way I've just (hopefully!) addressed the review comments with the latest commits - let me know if they're OK, or if there are any other bits to look at :-)

@dennisdoomen dennisdoomen merged commit ca4f63e into fluentassertions:master Apr 29, 2021
@dennisdoomen
Copy link
Copy Markdown
Member

Thank you for your contribution.

@dennisdoomen
Copy link
Copy Markdown
Member

Crap. Completely forgot to ask @jnyrup to also take a peek...

@rikrak rikrak deleted the ShouldBeJsonSerializable branch April 29, 2021 14:03
Copy link
Copy Markdown
Member

@jnyrup jnyrup left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was thinking out giving this a view later today.

Aside from the single question about inheritance, it looks good to me.

public static class ObjectAssertionsExtensions
{
/// <summary>
/// Asserts that an object can be serialized and deserialized using the JSON serializer and that it stills retains
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"stills retains" -> "still retains"

Comment on lines +111 to +113
.Which.Message
.Should().Contain("value is null")
.And.Contain("Please provide a value for the assertion");
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tip, it should be possible to shorten this to:

.WithMessage("*value is null*Please provide a value for the assertion*");

Comment on lines +96 to +101
private static object CreateCloneUsingJsonSerializer(object subject)
{
var serializedObject = JsonConvert.SerializeObject(subject);
var cloneUsingJsonSerializer = JsonConvert.DeserializeObject(serializedObject, subject.GetType());
return cloneUsingJsonSerializer;
}
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does it make any difference if we use subject.GetType() or typeof(T)?
E.g. for inheritance and interfaces.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like using typeof(T) causes issues with the non-generic overload of BeJsonSerialisable as T is object which causes problems with the equivalency of the deserialised object. Essentially a dynamic object is deserialised that doesn't play well with the IsEquivalentTo test. In addition the deserialised dynamic object has only string properties rather than, for example, Guids or DateTimes that the original instance had.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants