Fluent Assertions: XElement .Should().HaveValueContaining?

495 views Asked by At

I want to test that an XML element's value contains a particular string. [The code below is clearly highly contrived and not from the real codebase I am working on]. How to check with Fluent Assertions that the XElement's Value contains a string?

using System.Xml.Linq;
using FluentAssertions;

class Program
{
    private static void Main()
    {
        var x = new XElement("Root", new XElement("Name", "Fat Cat Sat"));
        x.Should().HaveElement("Name").Which.Should().HaveValue("Fat Cat Sat");

        // don't know how to do this:
        x.Should().HaveElement("Name").Which.Should().HaveValueContaining("Cat");
    }
}
2

There are 2 answers

0
gunr2171 On

The value of your XML node is just a string, having multiple "entries" separated by spaces isn't anything special in XML - so we need to treat this assertion as if it's a normal string.

x.Should().HaveElement("Name").Which.Value.Split(' ').Should().Contain("Cat");

The important difference here is .Which.Value, so that we are only asserting on the value of the node (which is a string), rather than the entire node. From there, you can split by spaces, then check if the resulting collection contains one of the entries you're looking for.

0
stuartd On

FluentAssertions can be extended, so you could add an extension method which checks the text is contained in the value:

public static class FluentExtensions {
    public static AndConstraint<XElementAssertions> HaveValueContaining(this XElementAssertions element, string text) {
        {
            Execute.Assertion
                .ForCondition(element.Subject.Value.Contains(text))
                .FailWith($"Element value does not contain '{text}'");

            return new AndConstraint<XElementAssertions>(element);
        }
    }
}

Then this test will pass:

[Test]
public void Test() {
    var x = new XElement("Root", new XElement("Name", "Fat Cat Sat"));
    x.Should().HaveElement("Name").Which.Should().HaveValue("Fat Cat Sat");

    x.Should().HaveElement("Name").Which.Should().HaveValueContaining("Cat");
    x.Should().HaveElement("Name").Which.Should().HaveValueContaining("Cat Sat");
}

And this test will fail:

[Test]
public void Test() {
    var x = new XElement("Root", new XElement("Name", "Fat Cat Sat"));
    x.Should().HaveElement("Name").Which.Should().HaveValue("Fat Cat Sat");

    x.Should().HaveElement("Name").Which.Should().HaveValueContaining("Cat Mat");
}

Element value does not contain 'Cat Mat'