Suppose my method-under-test looks like this:
public void TestMe()
{
DataSet d1 = null;
DataSet d2 = null;
bool process = false;
Helper helper = new Helper();
process = helper.LoadFromDB(out d1, out d2) && d1 != null && d1.Tables[0] != null && d1.Tables[0].Count > 0
if (process)
{
[...run business logic here...]
}
else
{
throw new Exception("Failed to load data from the db");
}
}
In order to circumvent using a physical database, I mock "helper.LoadFromDB" in my unit test. The delegate I use in the "DoInstead" method populates the test1DS and test2DS datasets with made-up data, and the "Returns" in my arrange returns true.
Mock.Arrange(() => helper.LoadFromDB(out test1DS, out test2DS))
.DoInstead(someDelegate)
.Returns(true);
The problem is that the data sets the mock implementation populates are the ones declared within the unit test, not the ones declared in the method-under-test. So the process flag in the code snippet above still returns false (due to d1 being null), and the business logic I wanted to test (within the "if (process)" block above) never gets run.
Is there a way to map (for lack of a better word) the test1DS and test2DS (that I declared in the unit test code and populated in my DoInstead delegate) to the data sets d1 and d2 declared within the method-under-test, so as to allow the process flag to evaluate to true once the mocked implementation has run?
Thanks,
Asim
Mock.Arrange(() => helper.LoadFromDB(out testDS1, out testDS2)).Returns(true);
After that, the " && d1 != null && d1.Tables[0] != null && d1.Tables[0].Count > 0" test (in the method-under-test) did pass.
This raises a very interesting question: Why is it that when I put the logic to instantiate and populate out parameters testDS1 and testDS2 in the body of the unit test method itself, the mocking works fine, but when I put the logic to instantiate and populate out parameters testDS1 and testDS2 in the Action delegate used in the "DoInstead", the method-under-test (that invokes the method that was mocked) sees these out parameters as null (i.e., un-initialized)? Is it a bug or by design?
Thanks,
Asim