How to replace Assert.Fail() with FluentAssertions
Asked Answered
L

4

23

We are currently converting some code that was using Assert.IsTrue(), Assert.AreEqual(), Assert.IsNotNull(), etc. The basic unit test assert Library for C#

We want to use FluentAssertions, like value.Should().BeNull().

I'm stuck on a few tests using Assert.Fail() in some locations. What should I use to efficiently replace those, since we want to do away with every single "Assert.*", and I can't find an equivalent in FluentAssertions?

Here is an example

[TestMethod, TestCategory("ImportantTest")]
public void MethodToTest_Circumstances_ExpectedResult()
{
    // Arrange
    var variable1 = new Type1() { Value = "hello" };
    var variable2 = new Type2() { Name = "Bob" };

    // Act
    try
    {
        MethodToTest(variable1, variable2);
        // This method should have thrown an exception
        Assert.Fail();
    }
    catch (Exception ex)
    {
        ex.Should().BeOfType<DataException>();
        ex.Message.Should().Be(Constants.DataMessageForMethod);
    }

    // Assert
    // test that variable1 was changed by the method
    variable1.Should().NotBeNull();
    variable1.Value.Should().Be("Hello!");
    // test that variable2 is unchanged because the method threw an exception before changing it
    variable2.Should().NotBeNull();
    variable2.Name.Should().Be("Bob");
}
Len answered 11/7, 2017 at 13:13 Comment(3)
Please post code samples of what you're stuck on. Unit testing is an art. We can't answer "What should I use to efficiently replace those..." without seeing what "those" are.Catoptrics
Usually an Assert.Fail is used in a code path that was reached because of a problem like if(value == null) { Assert.Fail("should not be null");} so how you convert them is completely based on the circumstances that lead the code to reach them.Slotnick
Sounds like you should be using Assert.Throws to start with, instead of the try/Assert.Fail/catch approach.Jedediah
T
15

Restructure the test to utilize the .ShouldThrow<> assertion extension.

[TestMethod, TestCategory("ImportantTest")]
public void MethodToTest_Circumstances_ExpectedResult() {
    // Arrange
    var variable1 = new Type1() { Value = "hello" };
    var variable2 = new Type2() { Name = "Bob" };

    // Act
    Action act = () => MethodToTest(variable1, variable2);       

    // Assert
    // This method should have thrown an exception
    act.ShouldThrow<DataException>()
       .WithMessage(Constants.DataMessageForMethod);
    // test that variable1 was changed by the method
    variable1.Should().NotBeNull();
    variable1.Value.Should().Be("Hello!");
    // test that variable2 is unchanged because the method threw an exception before changing it
    variable2.Should().NotBeNull();
    variable2.Name.Should().Be("Bob");
}

In the above example, if the expected exception is not thrown the the assertion would fail, stopping the test case.

You should review the documentation on asserting exceptions to get a better understanding of how to use the library.

Teneshatenesmus answered 11/7, 2017 at 14:39 Comment(0)
M
3

Following the example in here, he just dealt away with the Assert.Fail -- and use action and .ShouldThrow http://www.continuousimprover.com/2011/07/why-i-created-fluent-assertions-in.html

Menis answered 11/7, 2017 at 13:48 Comment(0)
P
3

As others have mentioned, in your specific example you should probably use ShouldThrow<>().

However, in general, if no other FluentAssertions method applies, you can use:

Execute.Assertion.FailWith("[explain why this line should not be reached]");
Peccadillo answered 4/1 at 9:46 Comment(0)
P
2

I think this is equivalent:

throw new AssertionFailedException("Reason...");

Pepillo answered 5/6, 2023 at 7:48 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.