I'm currently writing some unit tests in xUnit. Till now, I was using MSTest for UT, so every testcase was single test in file. With xUnit, I can use parametrized tests. What I'm not sure in using them, what is more common or I shoud use more.
My method I'm testing is simple - it takes decimal number and converts it to string with certain attributes. Test have always same code, it differs just in input and output. Example below is simplified version, but I think it still expresses the point.
[Fact]
public void valueIsZero()
{
var formattedValue = Formatter.Format(0m);
Assert.Equal("0", formattedValue);
}
[Fact]
public void valueIsOne()
{
var formattedValue = Formatter.Format(1m);
Assert.Equal("1", formattedValue);
}
This is the way I would write tests in MSTest, but in xUnit I can write those tests with theory like this:
public static IEnumerable<object[]> Data =>
new List<object[]>
{
new object[] { 0m, "0" },
new object[] { 1m, "1" }
};
[Theory]
[MemberData(nameof(Data))]
public void multipleValue(decimal value, string expectedResult)
{
var formattedValue = Formatter.Format(value, true, false, true);
Assert.Equal(expectedResult, formattedValue);
}
Are there any benefits or disadvantages with first or second approach? Or which approach is more common?
Test code should be treated like production code. So general principles like SOLID, DRY, ... apply as well.
The Theory construct in xUnit helps to avoid repeating test code. This makes maintenance in the future easier (only one place to change logic). Consider if your program logic will change due to changed requirements. Then you adjust the program logic and the tests as well. It is less work to change one Theory-Test than multiple Fact-Tests.
For your example I suggest to use InlineData like this:
[Theory]
[InlineData("0", "0")]
[InlineData("1", "1")]
public void multipleValue(string value, string expectedResult)
{
var formattedValue = Formatter.Format(Convert.ToDecimal(value), true, false, true);
Assert.Equal(expectedResult, formattedValue);
}
This leads to a nice display in the Testrunner of VisualStudio, because the analyser recognizes each InlineData as a single unit test and displays them as a group.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With