Search code examples
c#unit-testingfluent-assertions

FluentAssertions Asserting an Exception has been thrown for an overloaded operator


I've been using FluentAssertions for my unit testing, and have started looking at asserting whether Exceptions are thrown correctly. I know that I can use the ExpectedExceptions method attribute, but I would like to learn the FluentAssertion approach if it is possible.

I have a Matrix class (simplified for this example) with an overloaded multiplication operator:

public class Matrix
{
    public int Rows { get; set; }
    public int Columns { get; set; }
    public float[,] Elements { get; set; }

    public static Matrix operator *(Matrix m1, Matrix m2)
    {
        if (m1.Columns != m2.Rows)
        {
            throw new Exception("These matrices cant be multiplied");
        }

        return new Matrix(1, 2, new float[,] { {1, 2} });
    }
}

and I would like to test for the Exception case. This is what I have so far:

[TestMethod]
//[ExpectedException(typeof(Exception), "These matrices cant be multiplied")]
public void MatrixMultiplication_IncorrectMatrixSize_ExceptionTest()
{
    // Arrange
    var elementsA = new float[,]
    {
        {4, 7},
        {6, 8}
    };

    var elementsB = new float[,]
    {
        {3, 0},
        {1, 1},
        {5, 2}
    };

    Matrix A = new Matrix() {Rows=2, Columns=2, Elements=elementsA);
    Matrix B = new Matrix() {Rows=3, Columns=2, Elements=elementsB);

    // Act
    Func<Matrix, Matrix, Matrix> act = (mA, mB) => mA * mB;

    // Assert
    act(A,B).ShouldThrow<Exception>().WithInnerMessage("These matrices cant be multiplied");
}

The problem I'm having is that FluentAssertions doesn't have a ShouldThrow extension method for a generic Func, and I'm not sure if or how to wrap this in an Action. Is it possible to use FluentAssertions in this way for this situation, or do I use FluentAssertions in a different manner, or will I have to use ExpectedExceptions?


Solution

  • Hooray for overthinking the problem...

    Writing the TestMethod like this made it work:

    [TestMethod]
    public void MatrixMultiplication_IncorrectMatrixSize_ExceptionTest()
    {
        // Arrange
        var elementsA = new float[,]
        {
            {4, 7},
            {6, 8}
        };
    
        var elementsB = new float[,]
        {
            {3, 0},
            {1, 1},
            {5, 2}
        };
    
        Matrix A = new Matrix() {Rows=2, Columns=2, Elements=elementsA);
        Matrix B = new Matrix() {Rows=3, Columns=2, Elements=elementsB);
    
        // Act
        Action act = () => { var x = A * B; };
    
        // Assert
        act.ShouldThrow<Exception>().WithMessage("These matrices cant be multiplied");
    }