1

I'm trying to compare two objects with multiple properties, but need specific properties to be compared using a predicate (object1does not have exact values for those properties at object2, so I need to compare partial strings there).

So, I'm trying:

object1.Should().BeEquivalentTo(object2, options => options
    .Including(o => o.Property1.StartsWith("something"))
    .Including(o => o.Property2.StartsWith("something else")
);

I expect all other properties be compared as usual.

However, running the code above throws exception:

Message: System.ArgumentException : Expression <Convert(o.Property1.StartsWith("something"), Object)> cannot be used to select a member. Parameter name: expression

I checked documentation and it has the same example as mine (chapter "Selecting Members" at https://fluentassertions.com/objectgraphs/).

Why does this exception occur and how do I fix it?

Nkosi
  • 235,767
  • 35
  • 427
  • 472
YMM
  • 632
  • 1
  • 10
  • 21
  • @Nkosi What do you mean "a better example"? I have two objects of the same type with a set of string properties. I want to assert these objects are equal, but for some specific properties the assertion should be done based on a predicate (.StartsWith()). – YMM Jul 28 '19 at 23:20
  • Assertion is that `object1.Property1.StartsWith("https://www.google.com")` equals `object2.Property1 = "https://www.google.com/search?q=test"`. – YMM Jul 28 '19 at 23:24

1 Answers1

5

Why does this exception occur

The exception occurs because you are calling a function

.Including(o => o.Property1.StartsWith("something")) //<-- expects property only

in an expression that only expects to get a property expression.

.Including(o => o.Property1) //<-- expects property only

Referencing the same documentation linked in your original question, your example will only include the specified members when doing the comparison.

With what you are trying to do, you should look at the Equivalency Comparison Behavior section, which based on your comments, might look something like the below example

[TestClass]
public class ObjectEquivalencyTests {
    [TestMethod]
    public void ShouldBeEquivalent() {

        var expected = new MyObject {
            Property1 = "https://www.google.com",
            Property2 = "something else"
        };

        var actual = new MyObject {
            Property1 = "https://www.google.com/search?q=test",
            Property2 = "something else"
        };

        actual.Should().BeEquivalentTo(expected, options => options
            .Using<string>(ctx => ctx.Subject.Should().StartWith(ctx.Expectation))
            .When(info => info.SelectedMemberPath == "Property1")
        );
    }
}

public class MyObject {
    public string Property1 { get; set; }
    public string Property2 { get; set; }
}
Nkosi
  • 235,767
  • 35
  • 427
  • 472