<!-- GENERATED FILE - DO NOT EDIT This file was generated by [MarkdownSnippets](https://github.com/SimonCropp/MarkdownSnippets). Source File: /docs/mdsource/serializer-settings.source.md To change this file edit the source file and then run MarkdownSnippets. --> # Serializer settings Verify uses [Argon](https://github.com/SimonCropp/Argon) for serialization. See [Default Settings](#default-settings) for on how Argon is used and instructions on how to control that usage. Serialization settings can be customized at three levels: * Method: Will run the verification in the current test method. * Class: Will run for all verifications in all test methods for a test class. * Global: Will run for test methods on all tests. ## Not valid json Note that the output is technically not valid json. * Names and values are not quoted. * Newlines are not escaped. The reason for these is that it makes approval files cleaner and easier to read and visualize/understand differences. ### UseStrictJson To use strict json call `VerifierSettings.UseStrictJson`: #### Globally <!-- snippet: UseStrictJsonGlobal --> <a id='snippet-UseStrictJsonGlobal'></a> ```cs [ModuleInitializer] public static void Init() => VerifierSettings.UseStrictJson(); ``` <sup><a href='/src/StrictJsonTests/ModuleInit.cs#L3-L9' title='Snippet source file'>snippet source</a> | <a href='#snippet-UseStrictJsonGlobal' title='Start of snippet'>anchor</a></sup> <!-- endSnippet --> #### Instance <!-- snippet: UseStrictJson --> <a id='snippet-UseStrictJson'></a> ```cs var target = new TheTarget { Value = "Foo" }; var settings = new VerifySettings(); settings.UseStrictJson(); await Verify(target, settings); ``` <sup><a href='/src/Verify.Tests/Serialization/SerializationTests.cs#L622-L632' title='Snippet source file'>snippet source</a> | <a href='#snippet-UseStrictJson' title='Start of snippet'>anchor</a></sup> <!-- endSnippet --> #### Fluent <!-- snippet: UseStrictJsonFluent --> <a id='snippet-UseStrictJsonFluent'></a> ```cs var target = new TheTarget { Value = "Foo" }; await Verify(target) .UseStrictJson(); ``` <sup><a href='/src/Verify.Tests/Serialization/SerializationTests.cs#L638-L647' title='Snippet source file'>snippet source</a> | <a href='#snippet-UseStrictJsonFluent' title='Start of snippet'>anchor</a></sup> <!-- endSnippet --> #### Result Then this results in * The default `.received.` and `.verified.` extensions for serialized verification to be `.json`. * `JsonTextWriter.QuoteChar` to be `"`. * `JsonTextWriter.QuoteName` to be `true`. Then when an object is verified: <!-- snippet: UseStrictJsonVerify --> <a id='snippet-UseStrictJsonVerify'></a> ```cs var target = new TheTarget { Value = "Foo" }; await Verify(target); ``` <sup><a href='/src/StrictJsonTests/Tests.cs#L82-L90' title='Snippet source file'>snippet source</a> | <a href='#snippet-UseStrictJsonVerify' title='Start of snippet'>anchor</a></sup> <!-- endSnippet --> The resulting file will be: <!-- snippet: Tests.Object.verified.json --> <a id='snippet-Tests.Object.verified.json'></a> ```json { "Value": "Foo" } ``` <sup><a href='/src/StrictJsonTests/Tests.Object.verified.json#L1-L3' title='Snippet source file'>snippet source</a> | <a href='#snippet-Tests.Object.verified.json' title='Start of snippet'>anchor</a></sup> <!-- endSnippet --> ## Default settings Verify uses [Argon](https://github.com/SimonCropp/Argon) for serialization. > Argon is a JSON framework for .NET. It is a hard fork of Newtonsoft.Json. See [Argon documentation](https://github.com/SimonCropp/Argon/blob/main/docs/readme.md) The default `JsonSerializerSettings` are: <!-- snippet: defaultSerialization --> <a id='snippet-defaultSerialization'></a> ```cs var settings = new JsonSerializerSettings { Formatting = Formatting.Indented, ReferenceLoopHandling = ReferenceLoopHandling.Ignore, DefaultValueHandling = DefaultValueHandling.Ignore }; ``` <sup><a href='/src/Verify/Serialization/SerializationSettings.cs#L85-L94' title='Snippet source file'>snippet source</a> | <a href='#snippet-defaultSerialization' title='Start of snippet'>anchor</a></sup> <!-- endSnippet --> ### Modify Defaults #### Globally <!-- snippet: AddExtraSettingsGlobal --> <a id='snippet-AddExtraSettingsGlobal'></a> ```cs VerifierSettings .AddExtraSettings(_ => _.TypeNameHandling = TypeNameHandling.All); ``` <sup><a href='/src/Verify.Tests/Serialization/SerializationTests.cs#L514-L520' title='Snippet source file'>snippet source</a> | <a href='#snippet-AddExtraSettingsGlobal' title='Start of snippet'>anchor</a></sup> <!-- endSnippet --> #### Instance <!-- snippet: AddExtraSettings --> <a id='snippet-AddExtraSettings'></a> ```cs [Fact] public Task AddExtraSettings() { var settings = new VerifySettings(); settings .AddExtraSettings( _ => _.SerializeError = (currentObject, originalObject, location, member, exception, handled) => Console.WriteLine(member)); return Verify("Value", settings); } ``` <sup><a href='/src/Verify.Tests/Serialization/SerializationTests.cs#L485-L498' title='Snippet source file'>snippet source</a> | <a href='#snippet-AddExtraSettings' title='Start of snippet'>anchor</a></sup> <!-- endSnippet --> #### Fluent <!-- snippet: AddExtraSettingsFluent --> <a id='snippet-AddExtraSettingsFluent'></a> ```cs [Fact] public Task AddExtraSettingsFluent() => Verify("Value") .AddExtraSettings( _ => _.SerializeError = (currentObject, originalObject, location, member, exception, handled) => Console.WriteLine(member)); ``` <sup><a href='/src/Verify.Tests/Serialization/SerializationTests.cs#L500-L509' title='Snippet source file'>snippet source</a> | <a href='#snippet-AddExtraSettingsFluent' title='Start of snippet'>anchor</a></sup> <!-- endSnippet --> ## QuoteName is false [JsonTextWriter.QuoteName](https://www.newtonsoft.com/json/help/html/P_Newtonsoft_Json_JsonTextWriter_QuoteName.htm) is set to false. The reason for this is that it makes approval files cleaner and easier to read and visualize/understand differences. ## Empty collections are ignored By default empty collections are ignored during verification. To disable this behavior globally use: <!-- snippet: DontIgnoreEmptyCollections --> <a id='snippet-DontIgnoreEmptyCollections'></a> ```cs VerifierSettings.DontIgnoreEmptyCollections(); ``` <sup><a href='/src/Verify.Tests/Serialization/SerializationTests.cs#L1584-L1588' title='Snippet source file'>snippet source</a> | <a href='#snippet-DontIgnoreEmptyCollections' title='Start of snippet'>anchor</a></sup> <!-- endSnippet --> ## Changing Json.NET settings Extra Json.NET settings can be made: ### Globally <!-- snippet: ExtraSettingsGlobal --> <a id='snippet-ExtraSettingsGlobal'></a> ```cs VerifierSettings.AddExtraSettings( _ => _.TypeNameHandling = TypeNameHandling.All); ``` <sup><a href='/src/Verify.Tests/Snippets/Snippets.cs#L120-L125' title='Snippet source file'>snippet source</a> | <a href='#snippet-ExtraSettingsGlobal' title='Start of snippet'>anchor</a></sup> <!-- endSnippet --> ### Instance <!-- snippet: ExtraSettingsInstance --> <a id='snippet-ExtraSettingsInstance'></a> ```cs var settings = new VerifySettings(); settings.AddExtraSettings( _ => _.TypeNameHandling = TypeNameHandling.All); ``` <sup><a href='/src/Verify.Tests/Snippets/Snippets.cs#L127-L133' title='Snippet source file'>snippet source</a> | <a href='#snippet-ExtraSettingsInstance' title='Start of snippet'>anchor</a></sup> <!-- endSnippet --> ### Json.NET Converter One common use case is to register a custom [JsonConverter](https://www.newtonsoft.com/json/help/html/CustomJsonConverter.htm). As only writing is required, to help with this there is `WriteOnlyJsonConverter`, and `WriteOnlyJsonConverter<T>`. <!-- snippet: CompanyConverter --> <a id='snippet-CompanyConverter'></a> ```cs class CompanyConverter : WriteOnlyJsonConverter<Company> { public override void Write(VerifyJsonWriter writer, Company company) => writer.WriteMember(company, company.Name, "Name"); } ``` <sup><a href='/src/Verify.Tests/Snippets/Snippets.cs#L143-L152' title='Snippet source file'>snippet source</a> | <a href='#snippet-CompanyConverter' title='Start of snippet'>anchor</a></sup> <!-- endSnippet --> <!-- snippet: JsonConverter --> <a id='snippet-JsonConverter'></a> ```cs VerifierSettings.AddExtraSettings( _ => _.Converters.Add(new CompanyConverter())); ``` <sup><a href='/src/Verify.Tests/Snippets/Snippets.cs#L137-L140' title='Snippet source file'>snippet source</a> | <a href='#snippet-JsonConverter' title='Start of snippet'>anchor</a></sup> <!-- endSnippet --> #### VerifyJsonWriter `VerifyJsonWriter` exposes the following members: * `Counter` property that gives programmatic access to the counting behavior used by [Guid](guids.md), [Date](dates.md), and [Id](#numeric-ids-are-scrubbed) scrubbing. * `Serializer` property that exposes the current `JsonSerializer`. * `Serialize(object value)` is a convenience method that calls `JsonSerializer.Serialize` passing in the writer instance and the `value` parameter. * `WriteProperty<T, TMember>(T target, TMember value, string name)` method that writes a property name and value while respecting other custom serialization settings eg [member converters](#converting-a-member), [ignore rules](#ignoring-a-type) etc. ## Scoped settings <!-- snippet: ScopedSerializer --> <a id='snippet-ScopedSerializer'></a> ```cs [Fact] public Task ScopedSerializer() { var person = new Person { GivenNames = "John", FamilyName = "Smith" }; var settings = new VerifySettings(); settings.AddExtraSettings(_ => _.TypeNameHandling = TypeNameHandling.All); return Verify(person, settings); } [Fact] public Task ScopedSerializerFluent() { var person = new Person { GivenNames = "John", FamilyName = "Smith" }; return Verify(person) .AddExtraSettings(_ => _.TypeNameHandling = TypeNameHandling.All); } ``` <sup><a href='/src/Verify.Tests/Serialization/SerializationTests.cs#L3924-L3951' title='Snippet source file'>snippet source</a> | <a href='#snippet-ScopedSerializer' title='Start of snippet'>anchor</a></sup> <!-- endSnippet --> Result: <!-- snippet: Verify.Xunit.Tests/VerifyObjectSamples.ScopedSerializer.verified.txt --> <a id='snippet-Verify.Xunit.Tests/VerifyObjectSamples.ScopedSerializer.verified.txt'></a> ```txt { $type: VerifyObjectSamples.Person, GivenNames: John, FamilyName: Smith } ``` <sup><a href='/src/Verify.Xunit.Tests/VerifyObjectSamples.ScopedSerializer.verified.txt#L1-L5' title='Snippet source file'>snippet source</a> | <a href='#snippet-Verify.Xunit.Tests/VerifyObjectSamples.ScopedSerializer.verified.txt' title='Start of snippet'>anchor</a></sup> <!-- endSnippet --> ## Ignoring a type To ignore all members that match a certain type: <!-- snippet: AddIgnoreType --> <a id='snippet-AddIgnoreType'></a> ```cs [Fact] public Task IgnoreType() { var target = new IgnoreTypeTarget { ToIgnore = new() { Property = "Value" }, ToIgnoreNullable = new() { Property = "Value" }, ToIgnoreByInterface = new() { Property = "Value" }, ToIgnoreByBase = new() { Property = "Value" }, ToIgnoreByBaseGeneric = new() { Property = "Value" }, ToIgnoreByType = new() { Property = "Value" }, ToInclude = new() { Property = "Value" }, ToIncludeNullable = new() { Property = "Value" }, ToIgnoreStruct = new("Value"), ToIgnoreStructNullable = new("Value"), ToIncludeStruct = new("Value"), ToIncludeStructNullable = new("Value") }; var settings = new VerifySettings(); settings.IgnoreMembersWithType<ToIgnore>(); settings.IgnoreMembersWithType<ToIgnoreByType>(); settings.IgnoreMembersWithType<InterfaceToIgnore>(); settings.IgnoreMembersWithType<BaseToIgnore>(); settings.IgnoreMembersWithType(typeof(BaseToIgnoreGeneric<>)); settings.IgnoreMembersWithType<ToIgnoreStruct>(); return Verify(target, settings); } [Fact] public Task IgnoreTypeFluent() { var target = new IgnoreTypeTarget { ToIgnore = new() { Property = "Value" }, ToIgnoreNullable = new() { Property = "Value" }, ToIgnoreByInterface = new() { Property = "Value" }, ToIgnoreByBase = new() { Property = "Value" }, ToIgnoreByBaseGeneric = new() { Property = "Value" }, ToIgnoreByType = new() { Property = "Value" }, ToInclude = new() { Property = "Value" }, ToIncludeNullable = new() { Property = "Value" }, ToIgnoreStruct = new("Value"), ToIgnoreStructNullable = new("Value"), ToIncludeStruct = new("Value"), ToIncludeStructNullable = new("Value") }; return Verify(target) .IgnoreMembersWithType<ToIgnore>() .IgnoreMembersWithType<ToIgnoreByType>() .IgnoreMembersWithType<InterfaceToIgnore>() .IgnoreMembersWithType<BaseToIgnore>() .IgnoreMembersWithType(typeof(BaseToIgnoreGeneric<>)) .IgnoreMembersWithType<ToIgnoreStruct>(); } ``` <sup><a href='/src/Verify.Tests/Serialization/SerializationTests.cs#L2791-L2896' title='Snippet source file'>snippet source</a> | <a href='#snippet-AddIgnoreType' title='Start of snippet'>anchor</a></sup> <!-- endSnippet --> Or globally: <!-- snippet: AddIgnoreTypeGlobal --> <a id='snippet-AddIgnoreTypeGlobal'></a> ```cs VerifierSettings.IgnoreMembersWithType<ToIgnore>(); ``` <sup><a href='/src/Verify.Tests/Serialization/SerializationTests.cs#L2778-L2782' title='Snippet source file'>snippet source</a> | <a href='#snippet-AddIgnoreTypeGlobal' title='Start of snippet'>anchor</a></sup> <!-- endSnippet --> Result: <!-- snippet: SerializationTests.IgnoreType.verified.txt --> <a id='snippet-SerializationTests.IgnoreType.verified.txt'></a> ```txt { ToInclude: { Property: Value }, ToIncludeNullable: { Property: Value }, ToIncludeStruct: { Property: Value }, ToIncludeStructNullable: { Property: Value } } ``` <sup><a href='/src/Verify.Tests/Serialization/SerializationTests.IgnoreType.verified.txt#L1-L14' title='Snippet source file'>snippet source</a> | <a href='#snippet-SerializationTests.IgnoreType.verified.txt' title='Start of snippet'>anchor</a></sup> <!-- endSnippet --> ## Scrub a type To scrub all members that match a certain type: <!-- snippet: AddScrubType --> <a id='snippet-AddScrubType'></a> ```cs [Fact] public Task ScrubType() { var target = new IgnoreTypeTarget { ToIgnore = new() { Property = "Value" }, ToIgnoreNullable = new() { Property = "Value" }, ToIgnoreByInterface = new() { Property = "Value" }, ToIgnoreByBase = new() { Property = "Value" }, ToIgnoreByBaseGeneric = new() { Property = "Value" }, ToIgnoreByType = new() { Property = "Value" }, ToInclude = new() { Property = "Value" }, ToIncludeNullable = new() { Property = "Value" }, ToIgnoreStruct = new("Value"), ToIgnoreStructNullable = new("Value"), ToIncludeStruct = new("Value"), ToIncludeStructNullable = new("Value") }; var settings = new VerifySettings(); settings.ScrubMembersWithType<ToIgnore>(); settings.ScrubMembersWithType<ToIgnoreByType>(); settings.ScrubMembersWithType<InterfaceToIgnore>(); settings.ScrubMembersWithType<BaseToIgnore>(); settings.ScrubMembersWithType(typeof(BaseToIgnoreGeneric<>)); settings.ScrubMembersWithType<ToIgnoreStruct>(); return Verify(target, settings); } [Fact] public Task ScrubTypeFluent() { var target = new IgnoreTypeTarget { ToIgnore = new() { Property = "Value" }, ToIgnoreNullable = new() { Property = "Value" }, ToIgnoreByInterface = new() { Property = "Value" }, ToIgnoreByBase = new() { Property = "Value" }, ToIgnoreByBaseGeneric = new() { Property = "Value" }, ToIgnoreByType = new() { Property = "Value" }, ToInclude = new() { Property = "Value" }, ToIncludeNullable = new() { Property = "Value" }, ToIgnoreStruct = new("Value"), ToIgnoreStructNullable = new("Value"), ToIncludeStruct = new("Value"), ToIncludeStructNullable = new("Value") }; return Verify(target) .ScrubMembersWithType<ToIgnore>() .ScrubMembersWithType<ToIgnoreByType>() .ScrubMembersWithType<InterfaceToIgnore>() .ScrubMembersWithType<BaseToIgnore>() .ScrubMembersWithType(typeof(BaseToIgnoreGeneric<>)) .ScrubMembersWithType<ToIgnoreStruct>(); } ``` <sup><a href='/src/Verify.Tests/Serialization/SerializationTests.cs#L2899-L3004' title='Snippet source file'>snippet source</a> | <a href='#snippet-AddScrubType' title='Start of snippet'>anchor</a></sup> <!-- endSnippet --> Or globally: <!-- snippet: AddScrubTypeGlobal --> <a id='snippet-AddScrubTypeGlobal'></a> ```cs VerifierSettings.ScrubMembersWithType<ToIgnore>(); ``` <sup><a href='/src/Verify.Tests/Serialization/SerializationTests.cs#L2784-L2788' title='Snippet source file'>snippet source</a> | <a href='#snippet-AddScrubTypeGlobal' title='Start of snippet'>anchor</a></sup> <!-- endSnippet --> Result: <!-- snippet: SerializationTests.ScrubType.verified.txt --> <a id='snippet-SerializationTests.ScrubType.verified.txt'></a> ```txt { ToIgnore: {Scrubbed}, ToIgnoreByType: {Scrubbed}, ToIgnoreByInterface: {Scrubbed}, ToIgnoreByBase: {Scrubbed}, ToIgnoreByBaseGeneric: {Scrubbed}, ToIgnoreNullable: {Scrubbed}, ToIgnoreStruct: {Scrubbed}, ToIgnoreStructNullable: {Scrubbed}, ToInclude: { Property: Value }, ToIncludeNullable: { Property: Value }, ToIncludeStruct: { Property: Value }, ToIncludeStructNullable: { Property: Value } } ``` <sup><a href='/src/Verify.Tests/Serialization/SerializationTests.ScrubType.verified.txt#L1-L22' title='Snippet source file'>snippet source</a> | <a href='#snippet-SerializationTests.ScrubType.verified.txt' title='Start of snippet'>anchor</a></sup> <!-- endSnippet --> ## Ignoring an instance To ignore instances of a type based on delegate: <!-- snippet: AddIgnoreInstance --> <a id='snippet-AddIgnoreInstance'></a> ```cs [Fact] public Task AddIgnoreInstance() { var target = new IgnoreInstanceTarget { ToIgnore = new() { Property = "Ignore" }, ToInclude = new() { Property = "Include" } }; var settings = new VerifySettings(); settings.IgnoreInstance<Instance>(_ => _.Property == "Ignore"); return Verify(target, settings); } [Fact] public Task AddIgnoreInstanceFluent() { var target = new IgnoreInstanceTarget { ToIgnore = new() { Property = "Ignore" }, ToInclude = new() { Property = "Include" } }; return Verify(target) .IgnoreInstance<Instance>(_ => _.Property == "Ignore"); } ``` <sup><a href='/src/Verify.Tests/Serialization/SerializationTests.cs#L2664-L2703' title='Snippet source file'>snippet source</a> | <a href='#snippet-AddIgnoreInstance' title='Start of snippet'>anchor</a></sup> <!-- endSnippet --> Or globally: <!-- snippet: AddIgnoreInstanceGlobal --> <a id='snippet-AddIgnoreInstanceGlobal'></a> ```cs VerifierSettings.IgnoreInstance<Instance>(_ => _.Property == "Ignore"); ``` <sup><a href='/src/Verify.Tests/Serialization/SerializationTests.cs#L2651-L2655' title='Snippet source file'>snippet source</a> | <a href='#snippet-AddIgnoreInstanceGlobal' title='Start of snippet'>anchor</a></sup> <!-- endSnippet --> Result: <!-- snippet: SerializationTests.AddIgnoreInstance.verified.txt --> <a id='snippet-SerializationTests.AddIgnoreInstance.verified.txt'></a> ```txt { ToInclude: { Property: Include } } ``` <sup><a href='/src/Verify.Tests/Serialization/SerializationTests.AddIgnoreInstance.verified.txt#L1-L5' title='Snippet source file'>snippet source</a> | <a href='#snippet-SerializationTests.AddIgnoreInstance.verified.txt' title='Start of snippet'>anchor</a></sup> <!-- endSnippet --> ## Scrub a instance To scrub instances of a type based on delegate: <!-- snippet: AddScrubInstance --> <a id='snippet-AddScrubInstance'></a> ```cs [Fact] public Task AddScrubInstance() { var target = new IgnoreInstanceTarget { ToIgnore = new() { Property = "Ignore" }, ToInclude = new() { Property = "Include" } }; var settings = new VerifySettings(); settings.ScrubInstance<Instance>(_ => _.Property == "Ignore"); return Verify(target, settings); } [Fact] public Task AddScrubInstanceFluent() { var target = new IgnoreInstanceTarget { ToIgnore = new() { Property = "Ignore" }, ToInclude = new() { Property = "Include" } }; return Verify(target) .ScrubInstance<Instance>(_ => _.Property == "Ignore"); } ``` <sup><a href='/src/Verify.Tests/Serialization/SerializationTests.cs#L2705-L2744' title='Snippet source file'>snippet source</a> | <a href='#snippet-AddScrubInstance' title='Start of snippet'>anchor</a></sup> <!-- endSnippet --> Or globally: <!-- snippet: AddScrubInstanceGlobal --> <a id='snippet-AddScrubInstanceGlobal'></a> ```cs VerifierSettings.ScrubInstance<Instance>(_ => _.Property == "Ignore"); ``` <sup><a href='/src/Verify.Tests/Serialization/SerializationTests.cs#L2657-L2661' title='Snippet source file'>snippet source</a> | <a href='#snippet-AddScrubInstanceGlobal' title='Start of snippet'>anchor</a></sup> <!-- endSnippet --> Result: <!-- snippet: SerializationTests.AddScrubInstance.verified.txt --> <a id='snippet-SerializationTests.AddScrubInstance.verified.txt'></a> ```txt { ToIgnore: {Scrubbed}, ToInclude: { Property: Include } } ``` <sup><a href='/src/Verify.Tests/Serialization/SerializationTests.AddScrubInstance.verified.txt#L1-L6' title='Snippet source file'>snippet source</a> | <a href='#snippet-SerializationTests.AddScrubInstance.verified.txt' title='Start of snippet'>anchor</a></sup> <!-- endSnippet --> ## Ignore member by expressions To ignore members of a certain type using an expression: <!-- snippet: IgnoreMemberByExpression --> <a id='snippet-IgnoreMemberByExpression'></a> ```cs [Fact] public Task IgnoreMemberByExpression() { var target = new IgnoreExplicitTarget { Include = "Value", Field = "Value", Property = "Value", PropertyWithPropertyName = "Value" }; var settings = new VerifySettings(); settings.IgnoreMembers<IgnoreExplicitTarget>( _ => _.Property, _ => _.PropertyWithPropertyName, _ => _.Field, _ => _.GetOnlyProperty, _ => _.PropertyThatThrows); return Verify(target, settings); } [Fact] public Task IgnoreMemberByExpressionFluent() { var target = new IgnoreExplicitTarget { Include = "Value", Field = "Value", Property = "Value" }; return Verify(target) .IgnoreMembers<IgnoreExplicitTarget>( _ => _.Property, _ => _.Field, _ => _.GetOnlyProperty, _ => _.PropertyThatThrows); } ``` <sup><a href='/src/Verify.Tests/Serialization/SerializationTests.cs#L3220-L3259' title='Snippet source file'>snippet source</a> | <a href='#snippet-IgnoreMemberByExpression' title='Start of snippet'>anchor</a></sup> <!-- endSnippet --> Or globally <!-- snippet: IgnoreMemberByExpressionGlobal --> <a id='snippet-IgnoreMemberByExpressionGlobal'></a> ```cs VerifierSettings.IgnoreMembers<IgnoreExplicitTarget>( _ => _.Property, _ => _.PropertyWithPropertyName, _ => _.Field, _ => _.GetOnlyProperty, _ => _.PropertyThatThrows); ``` <sup><a href='/src/Verify.Tests/Serialization/SerializationTests.cs#L3197-L3206' title='Snippet source file'>snippet source</a> | <a href='#snippet-IgnoreMemberByExpressionGlobal' title='Start of snippet'>anchor</a></sup> <!-- endSnippet --> Result: <!-- snippet: SerializationTests.IgnoreMemberByExpression.verified.txt --> <a id='snippet-SerializationTests.IgnoreMemberByExpression.verified.txt'></a> ```txt { Include: Value } ``` <sup><a href='/src/Verify.Tests/Serialization/SerializationTests.IgnoreMemberByExpression.verified.txt#L1-L3' title='Snippet source file'>snippet source</a> | <a href='#snippet-SerializationTests.IgnoreMemberByExpression.verified.txt' title='Start of snippet'>anchor</a></sup> <!-- endSnippet --> ## Scrub member by expressions To scrub members of a certain type using an expression: <!-- snippet: ScrubMemberByExpression --> <a id='snippet-ScrubMemberByExpression'></a> ```cs [Fact] public Task ScrubMemberByExpression() { var target = new IgnoreExplicitTarget { Include = "Value", Field = "Value", Property = "Value", PropertyWithPropertyName = "Value" }; var settings = new VerifySettings(); settings.ScrubMembers<IgnoreExplicitTarget>( _ => _.Property, _ => _.PropertyWithPropertyName, _ => _.Field, _ => _.GetOnlyProperty, _ => _.PropertyThatThrows); return Verify(target, settings); } [Fact] public Task ScrubMemberByExpressionFluent() { var target = new IgnoreExplicitTarget { Include = "Value", Field = "Value", Property = "Value" }; return Verify(target) .ScrubMembers<IgnoreExplicitTarget>( _ => _.Property, _ => _.Field, _ => _.GetOnlyProperty, _ => _.PropertyThatThrows); } ``` <sup><a href='/src/Verify.Tests/Serialization/SerializationTests.cs#L3261-L3300' title='Snippet source file'>snippet source</a> | <a href='#snippet-ScrubMemberByExpression' title='Start of snippet'>anchor</a></sup> <!-- endSnippet --> Or globally <!-- snippet: ScrubMemberByExpressionGlobal --> <a id='snippet-ScrubMemberByExpressionGlobal'></a> ```cs VerifierSettings.ScrubMembers<IgnoreExplicitTarget>( _ => _.Property, _ => _.PropertyWithPropertyName, _ => _.Field, _ => _.GetOnlyProperty, _ => _.PropertyThatThrows); ``` <sup><a href='/src/Verify.Tests/Serialization/SerializationTests.cs#L3208-L3217' title='Snippet source file'>snippet source</a> | <a href='#snippet-ScrubMemberByExpressionGlobal' title='Start of snippet'>anchor</a></sup> <!-- endSnippet --> Result: <!-- snippet: SerializationTests.ScrubMemberByExpression.verified.txt --> <a id='snippet-SerializationTests.ScrubMemberByExpression.verified.txt'></a> ```txt { Include: Value, Field: {Scrubbed}, Property: {Scrubbed}, _Custom: {Scrubbed}, GetOnlyProperty: {Scrubbed}, PropertyThatThrows: {Scrubbed} } ``` <sup><a href='/src/Verify.Tests/Serialization/SerializationTests.ScrubMemberByExpression.verified.txt#L1-L8' title='Snippet source file'>snippet source</a> | <a href='#snippet-SerializationTests.ScrubMemberByExpression.verified.txt' title='Start of snippet'>anchor</a></sup> <!-- endSnippet --> ## Ignore member by name To ignore members of a certain type using type and name: <!-- snippet: IgnoreMemberByName --> <a id='snippet-IgnoreMemberByName'></a> ```cs [Fact] public Task IgnoreMemberByName() { var target = new IgnoreExplicitTarget { Include = "Value", Field = "Value", Property = "Value", PropertyByName = "Value" }; var settings = new VerifySettings(); // For all types settings.IgnoreMember("PropertyByName"); // For a specific type settings.IgnoreMember(typeof(IgnoreExplicitTarget), "Property"); // For a specific type generic settings.IgnoreMember<IgnoreExplicitTarget>("Field"); // For a specific type with expression settings.IgnoreMember<IgnoreExplicitTarget>(_ => _.PropertyThatThrows); return Verify(target, settings); } [Fact] public Task IgnoreMemberByNameFluent() { var target = new IgnoreExplicitTarget { Include = "Value", Field = "Value", Property = "Value", PropertyByName = "Value" }; return Verify(target) // For all types .IgnoreMember("PropertyByName") // For a specific type .IgnoreMember(typeof(IgnoreExplicitTarget), "Property") // For a specific type generic .IgnoreMember<IgnoreExplicitTarget>("Field") // For a specific type with expression .IgnoreMember<IgnoreExplicitTarget>(_ => _.PropertyThatThrows); } ``` <sup><a href='/src/Verify.Tests/Serialization/SerializationTests.cs#L3390-L3443' title='Snippet source file'>snippet source</a> | <a href='#snippet-IgnoreMemberByName' title='Start of snippet'>anchor</a></sup> <!-- endSnippet --> Or globally: <!-- snippet: IgnoreMemberByNameGlobal --> <a id='snippet-IgnoreMemberByNameGlobal'></a> ```cs // For all types VerifierSettings.IgnoreMember("PropertyByName"); // For a specific type VerifierSettings.IgnoreMember(typeof(IgnoreExplicitTarget), "Property"); // For a specific type generic VerifierSettings.IgnoreMember<IgnoreExplicitTarget>("Field"); // For a specific type with expression VerifierSettings.IgnoreMember<IgnoreExplicitTarget>(_ => _.PropertyThatThrows); ``` <sup><a href='/src/Verify.Tests/Serialization/SerializationTests.cs#L3341-L3355' title='Snippet source file'>snippet source</a> | <a href='#snippet-IgnoreMemberByNameGlobal' title='Start of snippet'>anchor</a></sup> <!-- endSnippet --> Result: <!-- snippet: SerializationTests.IgnoreMemberByName.verified.txt --> <a id='snippet-SerializationTests.IgnoreMemberByName.verified.txt'></a> ```txt { Include: Value, GetOnlyProperty: asd } ``` <sup><a href='/src/Verify.Tests/Serialization/SerializationTests.IgnoreMemberByName.verified.txt#L1-L4' title='Snippet source file'>snippet source</a> | <a href='#snippet-SerializationTests.IgnoreMemberByName.verified.txt' title='Start of snippet'>anchor</a></sup> <!-- endSnippet --> ## Scrub member by name To scrub members of a certain type using type and name: <!-- snippet: ScrubMemberByName --> <a id='snippet-ScrubMemberByName'></a> ```cs [Fact] public Task ScrubMemberByName() { var target = new IgnoreExplicitTarget { Include = "Value", Field = "Value", Property = "Value", PropertyByName = "Value" }; var settings = new VerifySettings(); // For all types settings.ScrubMember("PropertyByName"); // For a specific type settings.ScrubMember(typeof(IgnoreExplicitTarget), "Property"); // For a specific type generic settings.ScrubMember<IgnoreExplicitTarget>("Field"); // For a specific type with expression settings.ScrubMember<IgnoreExplicitTarget>(_ => _.PropertyThatThrows); return Verify(target, settings); } [Fact] public Task ScrubMemberByNameFluent() { var target = new IgnoreExplicitTarget { Include = "Value", Field = "Value", Property = "Value", PropertyByName = "Value" }; return Verify(target) // For all types .ScrubMember("PropertyByName") // For a specific type .ScrubMember(typeof(IgnoreExplicitTarget), "Property") // For a specific type generic .ScrubMember<IgnoreExplicitTarget>("Field") // For a specific type with expression .ScrubMember<IgnoreExplicitTarget>(_ => _.PropertyThatThrows); } ``` <sup><a href='/src/Verify.Tests/Serialization/SerializationTests.cs#L3445-L3498' title='Snippet source file'>snippet source</a> | <a href='#snippet-ScrubMemberByName' title='Start of snippet'>anchor</a></sup> <!-- endSnippet --> Or globally: <!-- snippet: ScrubMemberByNameGlobal --> <a id='snippet-ScrubMemberByNameGlobal'></a> ```cs // For all types VerifierSettings.ScrubMember("PropertyByName"); // For a specific type VerifierSettings.ScrubMember(typeof(IgnoreExplicitTarget), "Property"); // For a specific type generic VerifierSettings.ScrubMember<IgnoreExplicitTarget>("Field"); // For a specific type with expression VerifierSettings.ScrubMember<IgnoreExplicitTarget>(_ => _.PropertyThatThrows); ``` <sup><a href='/src/Verify.Tests/Serialization/SerializationTests.cs#L3357-L3371' title='Snippet source file'>snippet source</a> | <a href='#snippet-ScrubMemberByNameGlobal' title='Start of snippet'>anchor</a></sup> <!-- endSnippet --> Result: <!-- snippet: SerializationTests.ScrubMemberByName.verified.txt --> <a id='snippet-SerializationTests.ScrubMemberByName.verified.txt'></a> ```txt { Include: Value, Field: {Scrubbed}, Property: {Scrubbed}, PropertyByName: {Scrubbed}, GetOnlyProperty: asd, PropertyThatThrows: {Scrubbed} } ``` <sup><a href='/src/Verify.Tests/Serialization/SerializationTests.ScrubMemberByName.verified.txt#L1-L8' title='Snippet source file'>snippet source</a> | <a href='#snippet-SerializationTests.ScrubMemberByName.verified.txt' title='Start of snippet'>anchor</a></sup> <!-- endSnippet --> ## Ignore member by predicate To ignore members of a certain type using a predicate function: <!-- snippet: IgnoreMemberByPredicate --> <a id='snippet-IgnoreMemberByPredicate'></a> ```cs [Fact] public Task IgnoreMemberByPredicate() { var target = new IgnoreExplicitTarget { Include = "Value", Field = "Value", Property = "Value", PropertyByName = "Value" }; var settings = new VerifySettings(); settings.IgnoreMembers(_ => _ is "Field" or "Property"); settings.IgnoreMembers(_ => _.Name is "PropertyByName" or "PropertyThatThrows"); return Verify(target, settings); } [Fact] public Task IgnoreMemberByPredicateFluent() { var target = new IgnoreExplicitTarget { Include = "Value", Field = "Value", Property = "Value", PropertyByName = "Value" }; var settings = new VerifySettings(); return Verify(target, settings) .IgnoreMembers(_ => _ is "Field" or "Property") .IgnoreMembers(_ => _.Name is "PropertyByName" or "PropertyThatThrows"); } [Fact] public Task IgnoreDictionaryByPredicate() { var settings = new VerifySettings(); settings.IgnoreMembers(name => name is "Ignore"); var target = new Dictionary<string, object> { { "Include", new Dictionary<string, string> { { "Ignore", "Value1" }, { "Key1", "Value2" } } }, { "Ignore", "Value3" }, { "Key2", "Value4" } }; return Verify(target, settings); } ``` <sup><a href='/src/Verify.Tests/Serialization/SerializationTests.cs#L3569-L3635' title='Snippet source file'>snippet source</a> | <a href='#snippet-IgnoreMemberByPredicate' title='Start of snippet'>anchor</a></sup> <!-- endSnippet --> Or globally: <!-- snippet: IgnoreMemberByPredicateGlobal --> <a id='snippet-IgnoreMemberByPredicateGlobal'></a> ```cs VerifierSettings.IgnoreMembers( _=>_.DeclaringType == typeof(TargetClass) && _.Name == "Proprty"); ``` <sup><a href='/src/Verify.Tests/Serialization/SerializationTests.cs#L3380-L3386' title='Snippet source file'>snippet source</a> | <a href='#snippet-IgnoreMemberByPredicateGlobal' title='Start of snippet'>anchor</a></sup> <!-- endSnippet --> Result: <!-- snippet: SerializationTests.IgnoreMemberByPredicate.verified.txt --> <a id='snippet-SerializationTests.IgnoreMemberByPredicate.verified.txt'></a> ```txt { Include: Value, GetOnlyProperty: asd } ``` <sup><a href='/src/Verify.Tests/Serialization/SerializationTests.IgnoreMemberByPredicate.verified.txt#L1-L4' title='Snippet source file'>snippet source</a> | <a href='#snippet-SerializationTests.IgnoreMemberByPredicate.verified.txt' title='Start of snippet'>anchor</a></sup> <!-- endSnippet --> ## Scrub member by predicate To scrub members of a certain type using a predicate function: <!-- snippet: ScrubMemberByPredicate --> <a id='snippet-ScrubMemberByPredicate'></a> ```cs [Fact] public Task ScrubMemberByPredicate() { var target = new IgnoreExplicitTarget { Include = "Value", Field = "Value", Property = "Value", PropertyByName = "Value" }; var settings = new VerifySettings(); settings.ScrubMembers(_ => _ is "Field" or "Property"); settings.ScrubMembers(_ => _.Name is "PropertyByName" or "PropertyThatThrows"); return Verify(target, settings); } [Fact] public Task ScrubMemberByPredicateFluent() { var target = new IgnoreExplicitTarget { Include = "Value", Field = "Value", Property = "Value", PropertyByName = "Value" }; var settings = new VerifySettings(); return Verify(target, settings) .ScrubMembers(name => name is "Field" or "Property") .ScrubMembers(member => member.Name is "PropertyByName" or "PropertyThatThrows"); } [Fact] public Task ScrubDictionaryByPredicate() { var settings = new VerifySettings(); settings.ScrubMembers(name => name is "Ignore"); var target = new Dictionary<string, object> { { "Include", new Dictionary<string, string> { { "Ignore", "Value1" }, { "Key1", "Value2" } } }, { "Ignore", "Value3" }, { "Key2", "Value4" } }; return Verify(target, settings); } ``` <sup><a href='/src/Verify.Tests/Serialization/SerializationTests.cs#L3500-L3567' title='Snippet source file'>snippet source</a> | <a href='#snippet-ScrubMemberByPredicate' title='Start of snippet'>anchor</a></sup> <!-- endSnippet --> Or globally: <!-- snippet: ScrubMemberByPredicateGlobal --> <a id='snippet-ScrubMemberByPredicateGlobal'></a> ```cs VerifierSettings.ScrubMembers( _=>_.DeclaringType == typeof(TargetClass) && _.Name == "Proprty"); ``` <sup><a href='/src/Verify.Tests/Serialization/SerializationTests.cs#L3373-L3379' title='Snippet source file'>snippet source</a> | <a href='#snippet-ScrubMemberByPredicateGlobal' title='Start of snippet'>anchor</a></sup> <!-- endSnippet --> Result: <!-- snippet: SerializationTests.ScrubMemberByPredicate.verified.txt --> <a id='snippet-SerializationTests.ScrubMemberByPredicate.verified.txt'></a> ```txt { Include: Value, Field: {Scrubbed}, Property: {Scrubbed}, PropertyByName: {Scrubbed}, GetOnlyProperty: asd, PropertyThatThrows: {Scrubbed} } ``` <sup><a href='/src/Verify.Tests/Serialization/SerializationTests.ScrubMemberByPredicate.verified.txt#L1-L8' title='Snippet source file'>snippet source</a> | <a href='#snippet-SerializationTests.ScrubMemberByPredicate.verified.txt' title='Start of snippet'>anchor</a></sup> <!-- endSnippet --> ## Converting a member The value of a member can be mutated before serialization: <!-- snippet: MemberConverter --> <a id='snippet-MemberConverter'></a> ```cs [ModuleInitializer] public static void MemberConverterByExpressionInit() { // using only the member VerifierSettings.MemberConverter<MemberTarget, string>( expression: _ => _.Field, converter: _ => $"{_}_Suffix"); // using target and member VerifierSettings.MemberConverter<MemberTarget, string>( expression: _ => _.Property, converter: (target, member) => $"{target}_{member}_Suffix"); } [Fact] public Task MemberConverterByExpression() { var input = new MemberTarget { Field = "FieldValue", Property = "PropertyValue" }; return Verify(input); } ``` <sup><a href='/src/Verify.Tests/Serialization/SerializationTests.cs#L3302-L3330' title='Snippet source file'>snippet source</a> | <a href='#snippet-MemberConverter' title='Start of snippet'>anchor</a></sup> <!-- endSnippet --> ## See also * [Obsolete members](/docs/obsolete-members.md) * [Type to string mapping](/docs/type-to-string-mapping.md) * [Guids](/docs/guids.md) * [Dates](/docs/dates.md) * [Scrubbing](/docs/scrubbers.md) * [Members that throw](/docs/members-throw.md) * [Ordering](/docs/ordering.md) * [Encoding](/docs/encoding.md) * [JsonAppender](/docs/jsonappender.md)