So how to choose our unit test framework? Take a look at this discussion,
NUnit vs. MbUnit vs. MSTest vs. xUnit.net
In this article, we will use MSTest
for example, and learn how to use NSubstitute
for mocking and decoupling.
[TestClass]
public class UnitTestDemo
{
[TestMethod]
public void TestSplitCount()
{
var input = "Luke Skywalker, Leia Skywalker, Anakin Skywalker";
var expected = 3;
var actual = input.Split(',').Count();
Assert.AreEqual(expected, actual);
}
}
Assume that we have a class, SplitCounter
, which load the separator from configuration file (appsettings.json) as following,
public class SplitCounter
{
public ISplitConfig _splitConfig = null;
public SplitCounter()
{
this._splitConfig = new SplitConfig();
}
public int Calculate(string input)
{
if (this._splitConfig == null)
{
throw new NullReferenceException("SplitConfig is null!");
}
else
{
return input.Split(this._splitConfig.Separator).Count();
}
}
}
public interface ISplitConfig
{
char[] Separator { get; set; }
}
public class SplitConfig : ISplitConfig
{
public char[] Separator { get; set; }
public SplitConfig()
{
var builder = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json");
var configuration = builder.Build();
var separator = configuration["Separator"];
this.Separator = separator.ToCharArray();
}
}
{
"Separator": ","
}
However, we don’t want the SplitCounter
instance rely on anything from configuration file when unit-testing.
Let us use NSubstitute
to mock ISplitConfig
instance in SplitCounter
.
[TestMethod]
public void TestSplitCounterWithNSub()
{
#region Create the Substitutes
var splitConfig = Substitute.For<ISplitConfig>();
#endregion
#region Set the return value of the mock objects
splitConfig.Separator.Returns(new char[] { ';' });
#endregion
#region Intialize the test target
var splitCounter = new SplitCounter();
splitCounter._splitConfig = splitConfig;
#endregion
var input = "Luke Skywalker;Leia Skywalker;AnakinSkywalker";
var expected = 3;
var actual = splitCounter.Calculate(input);
Assert.AreEqual(expected, actual);
}