C# – Should Unit Test Expected Results Be Hardcoded?

cunit testing

Should the expected results of a unit test be hardcoded, or can they be dependant on initialised variables? Do hardcoded or calculated results increase the risk of introducing errors in the unit test? Are there other factors I haven't considered?

For instance, which of these two is a more reliable format?

[TestMethod]
public void GetPath_Hardcoded()
{
    MyClass target = new MyClass("fields", "that later", "determine", "a folder");
    string expected = "C:\\Output Folder\\fields\\that later\\determine\\a folder";
    string actual = target.GetPath();
    Assert.AreEqual(expected, actual,
        "GetPath should return a full directory path based on its fields.");
}

[TestMethod]
public void GetPath_Softcoded()
{
    MyClass target = new MyClass("fields", "that later", "determine", "a folder");
    string expected = "C:\\Output Folder\\" + string.Join("\\", target.Field1, target.Field2, target.Field3, target.Field4);
    string actual = target.GetPath();
    Assert.AreEqual(expected, actual,
        "GetPath should return a full directory path based on its fields.");
}

EDIT 1: In response to DXM's answer, is option 3 a preferred solution?

[TestMethod]
public void GetPath_Option3()
{
    string field1 = "fields";
    string field2 = "that later";
    string field3 = "determine";
    string field4 = "a folder";
    MyClass target = new MyClass(field1, field2, field3, field4);
    string expected = "C:\\Output Folder\\" + string.Join("\\", field1, field2, field3, field4);
    string actual = target.GetPath();
    Assert.AreEqual(expected, actual,
        "GetPath should return a full directory path based on its fields.");
}

Best Answer

I think calculated expected value results in more robust and flexible test cases. Also by using good variable names in the expression that calculate expected result, it is much more clear where the expected result came from in the first place.

Having said that, in your specific example I would NOT trust "Softcoded" method because it uses your SUT (system under test) as the input for your calculations. If there's a bug in MyClass where fields are not properly stored, your test will actually pass because your expected value calculation will use the wrong string just like target.GetPath().

My suggestion would be to calculate expected value where it makes sense, but make sure that the calculation doesn't depend on any code from the SUT itself.

In Response to OP's update to my response:

Yes, based on my knowledge but somewhat limited experience in doing TDD, I would choose option #3.

Related Topic