Skip to content

PropertyConstraint Causes Unexpected Behavior Because the Property's Value Is object Instead of the Property’s Actual Type #4998

Description

@LeQuackers

Overview:

As the title says, the PropertyConstraint can cause unexpected behavior in some cases because Actual<T>(T) is called with an object type argument instead of the property’s actual type:

_propValue = property.GetValue(actual, null);
var baseResult = BaseConstraint.ApplyTo(_propValue);
return new PropertyConstraintResult(this, baseResult);

Example:

One example of unexpected behavior is an interaction with DefaultConstraint, in which the assert fails even though the property is default:

[Test]
public void Example()
{
    var actual = new Foo
    {
        Bar = 0
    };

    Assert.Multiple(() =>
    {
        // passes
        Assert.That(actual.Bar, Is.Default);

        // fails
        Assert.That(actual, Has.Property(nameof(Foo.Bar)).Default);
    });
}
Assert.That(actual, Has.Property(nameof(Foo.Bar)).Default)
Expected: property Bar default
But was:  0

Proposed Solution:

Because IConstraint.Actual<T>(T) is a generic method, it's a bit awkward; we'd have to set the generic parameter and call it with reflection at runtime.

I'll link a pull request for it in a bit.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions