3

There is official example how to create CustomAssertion at FluentAssertions docs, however my attempt to apply it fails. Here's the code:

public abstract class BaseTest
{
    public List<int> TestList = new List<int>() { 1, 2, 3 };
}

public class Test : BaseTest { }


public class TestAssertions
{
    private readonly BaseTest test;

    public TestAssertions(BaseTest test)
    {
        this.test = test;
    }

    [CustomAssertion]
    public void BeWorking(string because = "", params object[] becauseArgs)
    {
        foreach (int num in test.TestList)
        {
            num.Should().BeGreaterThan(0, because, becauseArgs);
        }
    }
}

public class CustomTest
{
    [Fact]
    public void TryMe()
    {
        Test test = new Test();
        test.Should().BeWorking(); // error here
    }
}

I'm getting compile error:

CS1061 'ObjectAssertions' does not contain a definition for 'BeWorking' and no accessible extension method 'BeWorking' accepting a first argument of type 'ObjectAssertions' could be found (are you missing a using directive or an assembly reference?)

I also tried to move BeWorking from TestAssertions to BaseTest but it still won't work. What am I missing and how do I make it work?

  • Did you follow the instructions here https://fluentassertions.com/extensibility/ – Nkosi Nov 29 '19 at 13:46
  • Yes, but it doesn't help. I noticed that `using` statement for the namespace, containing `TestAssertions`'s namespace in CustomTest.cs is gray (not used). I gues that might be the clue. I managed to write my own extension method via syntax `BeWorking(this ObjectAssertions obj, string because="", params object[] becauseArgs)` in static class. But I still wonder how is it supposed to work using [FluentAssertions docs](https://fluentassertions.com/introduction). – Constantine Ketskalo Nov 29 '19 at 14:31
  • Is there any open source project with working code for what I'm trying to do or probably you have some of it and it worked for you? I feel like I'm missing some really tiny detail for my code to make it work. – Constantine Ketskalo Nov 29 '19 at 14:34

1 Answers1

10

You did a very good job actually :) The most important thing you are missing is the Extension class. I'll guide you through.

Add this class:

public static class TestAssertionExtensions
{
    public static TestAssertions Should(this BaseTest instance)
    {
        return new TestAssertions(instance);
    }
}

Fix your TestAssertions class like this:

public class TestAssertions : ReferenceTypeAssertions<BaseTest, TestAssertions>
{
    public TestAssertions(BaseTest instance) => Subject = instance;

    protected override string Identifier => "TestAssertion";

    [CustomAssertion]
    public AndConstraint<TestAssertions> BeWorking(string because = "", params object[] becauseArgs)
    {
        foreach (int num in Subject.TestList)
        {
            num.Should().BeGreaterThan(0, because, becauseArgs);
        }

        return new AndConstraint<TestAssertions>(this);
    }
}

Your TryMe() test should be working fine now. Good luck.

Koray Elbek
  • 794
  • 5
  • 13