5

If I have an expected object graph that includes a list, like so:

        var expectedExperiment = new Experiment
        {
            Number= "12345",
            AllocatedInstrument = "Instrument 1",
            Experimenters = new List<Experimenter>
            {
                new Experimenter
                {
                    Name = "Sue"
                    Role = "Scientist",
                    Id = 1,
                    Initials = "S"
                },
                new Experimenter()
                {
                    Name = "Mark",
                    Role = "Technician",
                    Id = 2,
                    Initials = "M"
                },
            }
        };

How can I compare it to my actual object when I only want to include certain properties on the list of child objects.

For example, I'd like to write something like this to compare all the parent object properties and some of the child object properties:

        actualExperiment.ShouldBeEquivalentTo(expectedExperiment, options => options
            .Including(o => o.Number)
            .Including(o => o.AllocatedInstrument)
            .Including(o => o.Experimenters.Select(e => e.Role))
            .Including(o => o.Experimenters.Select(e => e.Name)));

But I get an exception:

System.ArgumentException : Expression <o.Experimenters.Select(e => e.Role)> cannot be used to select a member.

I don't mind in this case what order the child items are in but I want to assert that properties I care about match expectation.

1 Answer 1

3

You can do this by checking run-time type and selected member path of current object:

.Including(subjectInfo => subjectInfo.RuntimeType == typeof(Experimenter) &&
                          subjectInfo.SelectedMemberPath.EndsWith("Role"))

This can be extracted to a method for further reuse:

private Expression<Func<ISubjectInfo, bool>> BuildMemberExpression<TSource, TProperty>(Expression<Func<TSource,TProperty>> propertySelector)
    {
        var memberExpression = propertySelector.Body as MemberExpression;
        if (memberExpression == null)
        {
            throw new NotSupportedException();
        }

        return subjectInfo => subjectInfo.RuntimeType == typeof(TSource) && 
                              subjectInfo.SelectedMemberPath.EndsWith(memberExpression.Member.Name);
    }

And now use it this way:

.Including(BuildMemberExpression((Experimenter e) => e.Name))
.Including(BuildMemberExpression((Experimenter e) => e.Role))
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.