.NET Unit Testing – Should Expected Value Be Hard-Coded in Assert?

conventionsnetnunitunit testing

My own personal preference would be to use a variable, but maybe there are reasons against this? I haven't been able to find any resources that state the pros or cons of using one of these over the other.

Option 1:

[TestClass]
public PersonAgeTest
{
  [Test]
  public void GetFullNameWithPrefix_Parameterless_ReturnsValueWithPrefix
  {
    // Arrange
    var person = new person(Gender.Male);
    var person.LastName = "Philips";
    var expected = "Mr. Philips";

    // Act
    var actual = person.GetSalutation(); 

    // Assert
    Assert.That(actual, Is.EqualTo(expected));
  }
}

Option 2:

[TestClass]
public PersonAgeTest
{
  [Test]
  public void GetFullNameWithPrefix_Parameterless_ReturnsValueWithPrefix
  {
    // Arrange
    var person = new person(Gender.Male);
    var person.LastName = "Philips";

    // Act
    var actual = person.GetSalutation(); 

    // Assert
    Assert.That(actual, Is.EqualTo("Mr. Philips"));
  }
}

Maybe it's too minor of a difference? I'm not sure, it seems better to ask.

Best Answer

I personally prefer to use the [TestCase] where the input and expected outputs are all passed as arguments to the test function, whenever possible:

[TestClass]
public class PersonAgeTest
{
    [TestCase("Philips","Mr. Phillips")]  
    public void GetFullNameWithPrefix_SimpleValue_ReturnsValueWithPrefix(string input, string expected)
      {
          // Arrange
          var person = new person(Gender.Male);
          var person.LastName = input;

          // Act
          var actual = person.GetSalutation();

          // Assert
          Assert.That(actual, Is.EqualTo(expected));
      }
}

There is even a way to also do some sort of specified return value as your TestCase arguments in the case of NUnit, but I don't remember off the top of my head how that works or what it's syntax is.

In situations where you can't or it isn't appropriate to pass your inputs and outputs in as parameters, I would define them all up front so you can quickly eyeball what you are feeding to your test. I have been burned plenty of times debugging stuff due to a failing test case, only to find a typo in my input. Grouping all that together makes things easier to deal with.

Related Topic