Skip to content

Latest commit

 

History

History
580 lines (467 loc) · 21.7 KB

serializer-settings.md

File metadata and controls

580 lines (467 loc) · 21.7 KB

Serializer settings

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.

Contents

Default settings

The default serialization settings are:

var settings = new JsonSerializerSettings
{
    Formatting = Formatting.Indented,
    ReferenceLoopHandling = ReferenceLoopHandling.Ignore,
    DefaultValueHandling = DefaultValueHandling.Ignore
};

snippet source | anchor

Single quotes used

JsonTextWriter.QuoteChar is set to single quotes '. The reason for this is that it makes approval files cleaner and easier to read and visualize/understand differences.

QuoteName is false

JsonTextWriter.QuoteName 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:

SharedVerifySettings.ModifySerialization(_ => _.DontIgnoreEmptyCollections());

snippet source | anchor

Guids are scrubbed

By default guids are sanitized during verification. This is done by finding each guid and taking a counter based that that specific guid. That counter is then used replace the guid values. This allows for repeatable tests when guid values are changing.

var guid = Guid.NewGuid();
var target = new GuidTarget
{
    Guid = guid,
    GuidNullable = guid,
    GuidString = guid.ToString(),
    OtherGuid = Guid.NewGuid(),
};

await Verify(target);

snippet source | anchor

Results in the following:

{
  Guid: Guid_1,
  GuidNullable: Guid_1,
  GuidString: Guid_1,
  OtherGuid: Guid_2
}

snippet source | anchor

To disable this behavior globally use:

SharedVerifySettings.ModifySerialization(_ => _.DontScrubGuids());

snippet source | anchor

Dates are scrubbed

By default dates (DateTime and DateTimeOffset) are sanitized during verification. This is done by finding each date and taking a counter based that that specific date. That counter is then used replace the date values. This allows for repeatable tests when date values are changing.

var dateTime = DateTime.Now;
var dateTimeOffset = DateTimeOffset.Now;
var target = new DateTimeTarget
{
    DateTime = dateTime,
    DateTimeNullable = dateTime,
    DateTimeString = dateTime.ToString("F"),
    DateTimeOffset = dateTimeOffset,
    DateTimeOffsetNullable = dateTimeOffset,
    DateTimeOffsetString = dateTimeOffset.ToString("F"),
};

await Verify(target);

snippet source | anchor

Results in the following:

{
  DateTime: DateTime_1,
  DateTimeNullable: DateTime_1,
  DateTimeOffset: DateTimeOffset_1,
  DateTimeOffsetNullable: DateTimeOffset_1,
  DateTimeString: DateTimeOffset_2,
  DateTimeOffsetString: DateTimeOffset_2
}

snippet source | anchor

To disable this behavior globally use:

SharedVerifySettings.ModifySerialization(_ => _.DontScrubDateTimes());

snippet source | anchor

Default Booleans are ignored

By default values of bool and bool? are ignored during verification. So properties that equate to 'false' will not be written,

To disable this behavior globally use:

SharedVerifySettings.ModifySerialization(_ => _.DontIgnoreFalse());

snippet source | anchor

Change defaults at the verification level

DateTime, DateTimeOffset, Guid, bool, and empty collection behavior can also be controlled at the verification level:

var settings = new VerifySettings();
settings.ModifySerialization(_ =>
{
    _.DontIgnoreEmptyCollections();
    _.DontScrubGuids();
    _.DontScrubDateTimes();
    _.DontIgnoreFalse();
});
await Verify(target, settings);

snippet source | anchor

var settings = new VerifySettings();
settings.ModifySerialization(_ =>
{
    _.DontIgnoreEmptyCollections();
    _.DontScrubGuids();
    _.DontScrubDateTimes();
    _.DontIgnoreFalse();
});
await Verifier.Verify(target, settings);

snippet source | anchor

Changing settings globally

To change the serialization settings for all verifications use Global.ApplyExtraSettings():

var settings = new VerifySettings();
settings.AddExtraSettings(_ =>
{
    _.DateFormatHandling = DateFormatHandling.MicrosoftDateFormat;
    _.TypeNameHandling = TypeNameHandling.All;
});

snippet source | anchor

Scoped settings

var person = new Person
{
    GivenNames = "John",
    FamilyName = "Smith",
    Dob = new DateTimeOffset(2000, 10, 1, 0, 0, 0, TimeSpan.Zero),
};
var settings = new VerifySettings();
settings.ModifySerialization(
    _ => _.DontScrubDateTimes());
settings.AddExtraSettings(
    _ => { _.DateFormatHandling = DateFormatHandling.MicrosoftDateFormat; });

snippet source | anchor

Result:

{
  GivenNames: 'John',
  FamilyName: 'Smith',
  Dob: '\/Date(970358400000+0000)\/'
}

snippet source | anchor

Ignoring a type

To ignore all members that match a certain type:

var settings = new VerifySettings();
settings.ModifySerialization(_ => _.IgnoreMembersWithType<ToIgnore>());

var target = new IgnoreTypeTarget
{
    ToIgnore = new ToIgnore
    {
        Property = "Value"
    },
    ToInclude = new ToInclude
    {
        Property = "Value"
    }
};
await Verify(target, settings);

snippet source | anchor

Result:

{
  ToInclude: {
    Property: 'Value'
  }
}

snippet source | anchor

Ignoring a instance

To ignore instances of a type based on delegate:

var settings = new VerifySettings();
settings.ModifySerialization(
    _ => { _.IgnoreInstance<Instance>(x => x.Property == "Ignore"); });

var target = new IgnoreInstanceTarget
{
    ToIgnore = new Instance
    {
        Property = "Ignore"
    },
    ToInclude = new Instance
    {
        Property = "Include"
    }
};
await Verify(target, settings);

snippet source | anchor

Result:

{
  ToInclude: {
    Property: 'Include'
  }
}

snippet source | anchor

Obsolete members ignored

Members with an ObsoleteAttribute are ignored:

class WithObsolete
{
    [Obsolete]
    public string ObsoleteProperty { get; set; }
    public string OtherProperty { get; set; }
}

[Fact]
public Task WithObsoleteProp()
{
    var target = new WithObsolete
    {
        ObsoleteProperty = "value1",
        OtherProperty = "value2"
    };
    return Verify(target);
}

snippet source | anchor

Result:

{
  OtherProperty: 'value2'
}

snippet source | anchor

Including Obsolete members

Obsolete members can be included using IncludeObsoletes:

[Fact]
public Task WithObsoletePropIncluded()
{
    var target = new WithObsolete
    {
        ObsoleteProperty = "value1",
        OtherProperty = "value2"
    };
    var settings = new VerifySettings();
    settings.ModifySerialization(_=> { _.IncludeObsoletes(); });
    return Verify(target, settings);
}

snippet source | anchor

Result:

{
  ObsoleteProperty: 'value1',
  OtherProperty: 'value2'
}

snippet source | anchor

Ignore member by expressions

To ignore members of a certain type using an expression:

var settings = new VerifySettings();
settings.ModifySerialization(_ =>
{
    _.IgnoreMember<IgnoreExplicitTarget>(x => x.Property);
    _.IgnoreMember<IgnoreExplicitTarget>(x => x.Field);
    _.IgnoreMember<IgnoreExplicitTarget>(x => x.GetOnlyProperty);
    _.IgnoreMember<IgnoreExplicitTarget>(x => x.PropertyThatThrows);
});

var target = new IgnoreExplicitTarget
{
    Include = "Value",
    Field = "Value",
    Property = "Value"
};
await Verify(target, settings);

snippet source | anchor

Result:

{
  Include: 'Value'
}

snippet source | anchor

Ignore member by name

To ignore members of a certain type using type and name:

var settings = new VerifySettings();
settings.ModifySerialization(_ =>
{
    var type = typeof(IgnoreExplicitTarget);
    _.IgnoreMember(type, "Property");
    _.IgnoreMember(type, "Field");
    _.IgnoreMember(type, "GetOnlyProperty");
    _.IgnoreMember(type, "PropertyThatThrows");
});

var target = new IgnoreExplicitTarget
{
    Include = "Value",
    Field = "Value",
    Property = "Value"
};
await Verify(target, settings);

snippet source | anchor

Result:

{
  Include: 'Value'
}

snippet source | anchor

Members that throw

Members that throw exceptions can be excluded from serialization based on the exception type or properties.

By default members that throw NotImplementedException or NotSupportedException are ignored.

Note that this is global for all members on all types.

Ignore by exception type:

var settings = new VerifySettings();
settings.ModifySerialization(_ => _.IgnoreMembersThatThrow<CustomException>());

var target = new WithCustomException();
await Verify(target, settings);

snippet source | anchor

Result:

{}

snippet source | anchor

Ignore by exception type and expression:

var settings = new VerifySettings();
settings.ModifySerialization(
    _ => _.IgnoreMembersThatThrow<Exception>(x => x.Message == "Ignore"));

var target = new WithExceptionIgnoreMessage();
await Verify(target, settings);

snippet source | anchor

Result:

{}

snippet source | anchor