Create a test for a void extension method

62 Views Asked by At

How exactly do you create a test for a void extension method? I'm using XUnit.

I have a extension method that throws an exception if something is true.

public static void IsClosed(this List<Contract> contracts)
{
    if (contracts.Any(x => x.Status == Status.Closed) throw new IsClosedException();
}

In the test I cannot ceate for example :

var sut = contracts.IsClosed();

Do I need to mock a list of contracts?

var contracts = Mock<List<Contract>>());

But what then?

contracts.Setup...?

Or

contracts.Invoke...?
1

There are 1 best solutions below

5
Fildor On BEST ANSWER
[Fact]
void ShouldThrowIsClosedException()
{
    // Just create a list that you expect to trigger the Exception ...
    List<Contract> contracts = new() { new() {Status == Status.Closed}};
   
    Assert.Throws<IsClosedException>(contracts.IsClosed);
}

should do the trick.

As remarked by Jon Skeet: A complementary test should be added, too. (I.e. where the exception is not thrown.)

If you want to get really fancy, you can also test different lists:

[Theory]
[ClassData(typeof(ShouldThrowIsClosedExceptionTestData))]
void ShouldThrowIsClosedException(List<Contract> contracts)
{
    Assert.Throws<IsClosedException>(contracts.IsClosed);
}

// ...
public class ShouldThrowIsClosedExceptionTestData 
    : TheroyData<List<Contract>>
{
    public ShouldThrowIsClosedExceptionTestData()
    {
// Single entry
        Add (new List<Contract>() { new() {Status == Status.Closed}});
// Multiple entries
        Add (new List<Contract>() { new() {Status == Status.Closed}, new() {Status == Status.Closed}});
// Mixed entries
        Add (new List<Contract>() { new() {Status == Status.Closed}, new() {Status == Status.Open}});
        Add (new List<Contract>() { new() {Status == Status.Open}, new() {Status == Status.Closed}});
    }
}