Emberace MemberData attribute.

Naming is hard. Well described test suites are even harder. I've seen a lot of tests that goes like this:

[MemberData(nameof(Data))]
public void EmailValidator_Should_Validate_Correctly(
    string data, bool expected)
{
  var emailValidator = new EmailValidator();
  var result = emailValidator.Validate(data);

  Assert.Equal(expected, result);
}

As you may expect, I wasn't happy with this boilerplate code as well.
But let's focus on something else. I see a few issues with the name of the test:

  • it doesn't describe any business behavior
  • it's hard to read because it doesn't follow English grammar
  • it includes the name of the service

Sadly, this is the desired template of any test you wrote in that specific codebase.

How can we convey any meaning in such a situation? Embrace the MemberData attribute!

Usually, our data collection has a few entries. It can look like this:

public static IEnumerable<object[]> Data =>
    new List<object[]>
    {
        new object[] {
            "donatello@example.com", true,
            "donatello.turtles@example.com", true,
            "leonardo@examplecom", false,
            "leonardo.example.com", false
        }
    };

Do you see the pattern? Try to make use of it and split the entries.
Divide it as follows:

public static IEnumerable<object[]> ValidEmails =>
 new List<object[]>
 {
   new object[] {
    "donatello@example.com", true,
    "donatello.the.turtle@example.com", true,
   }
 };
public static IEnumerable<object[]> InvalidEmails =>
 new List<object[]>
 {
   new object[] {
    "leonardo@examplecom", false,
    "leonardo.example.com", false
 }
};

Follow by the test:

[MemberData(nameof(ValidEmails))]
[MemberData(nameof(InvalidEmails))]
public void Should_Validate_Correctly(string data,bool expected)
{
    var emailValidator = new EmailValidator();
    var result = emailValidator.Validate(data);

    Assert.Equal(expected, result);
}

Of course, one could argue that it won't change much. We can't see that modification in a test runner window. And that's true. We have to open the file and read its content anyway. But it's a step in the right direction.