It is common practice to use an the TestCaseSource attribute to specify test data and the expected result in the format of IEnumerable<TestCaseData> like the example below.
[Test, TestCaseSource("TestCases")]
public int ShouldReturnTheExpectedValueWhenCalled(int testCase)
{
context.Setup(c => c.Number).Returns(testCase);
return context.CalculateSomething();
}
private IEnumerable<TestCaseData> TestCases
{
get
{
yield return new TestCaseData(4).Returns(16);
yield return new TestCaseData(5).Returns(25);
yield return new TestCaseData(-1).Throws(typeof( Exception));
}
}
For some tests the method shown above is sufficient but what about when you are testing a method that does not return a value and executes a command? In this circumstance you will be using mocking to assert that the method is operating correctly. The only problem with this is that I could not find any documentation for using a mock verification with TestCaseData, but I was able to get the functionality required from the example below.
[Test, TestCaseSource("TestCases")]
public void ShouldAlwaysCallSaveMethod(int testCase, Action[] verifications)
{
// Act
context.DoSomething(testCase);
// Assert
foreach (var verification in verifications)
{
verification.Invoke();
}
}
private IEnumerable<TestCaseData> TestCases
{
get
{
yield return new TestCaseData(random.Next(),
new Action[]
{
() => service.Verify(s => s.SomeAction(It.IsAny<int>()), Times.Once()),
() => service2.Verify(s => s.SomeAction(It.IsAny<int>()), Times.Once())
});
yield return new TestCaseData(0,
new Action[]
{
() => service.Verify(s => s.SomeAction(It.IsAny<int>()), Times.Once()),
() => service2.Verify(s => s.SomeAction(It.IsAny<int>()), Times.Never())
});
yield return new TestCaseData(-(random.Next()),
new Action[]
{
() => service.Verify(s => s.SomeAction(It.IsAny<int>()), Times.Never()),
() => service2.Verify(s => s.SomeAction(It.IsAny<int>()), Times.Never())
});
}
}