How to strip a class that is called more than once in a function under test using Microsoft fakes
Suppose I have a class and it has GetList () like this:
public class Foo
{
public List<Bar> GetList(string para);
}
And the tested function is like
public ResultType TestedFunc()
{
if( GetList("condition").count() == 1 )
{
//do arrange business
if( GetList("same condition as above".count() == 2 )
{
//do core business
}
else
{
return ResultType;
}
}
else
{
return ResultType
}
}
In my test method, I am using ShimFoo.AllInstance.GetList to align GetList (). Regardless of the strange business logic and call logic, my question is how can I get the first GetList () call and the second GetListh () call return different results, like lists that contain one and two objects respectively.
For further discussion, I want to know the difference between the so-called "fake" and what we already have - "mock"
I have read three official articles on MS Fake:
1. Isolate the code under the Microsoft counterfeit test
2. Using stubs to isolate parts of your application from each other for unit testing
3. Using shims to isolate your application from other assemblies for unit testing
but I haven't found a manual yet that can do what I do as described above.
I found out that behavior validation can be done on a mock test, there are many frameworks that can achieve this (like google mock). I can figure out how the mock class works, when it is called the first / second / third time, I can set a sequence to strictly limit the mock class. I wonder if MS Fakes can do the same.
Thanks guys.
source to share
You can just keep the call count by capturing the variable int
when you configure Shim.
[TestMethod]
public void TestMethod1()
{
using(ShimsContext.Create()) {
int counter = 0; // define the int outside of the delegate to capture it value between calls.
ShimFoo sfoo = new ShimFoo();
sfoo.GetListString = (param) =>
{
List<Bar> result = null;
switch (counter)
{
case 0: // First call
result = new Bar[] { }.ToList();
break;
case 1: // Second call
result = new Bar[] { new Bar() }.ToList();
break;
}
counter++;
return result;
};
Foo foo = sfoo.Instance;
Assert.AreEqual(0, foo.GetList("first").Count(), "First");
Assert.AreEqual(1, foo.GetList("second").Count(), "Second");
Assert.IsNull(foo.GetList("third"), "Third");
}
}
Or you can check the passed parameter and adjust the result accordingly.
[TestMethod]
public void TestMethod1()
{
using(ShimsContext.Create()) {
ShimFoo sfoo = new ShimFoo();
sfoo.GetListString = (param) =>
{
List<Bar> result = null;
switch (param)
{
case "first": // First call
result = new Bar[] { }.ToList();
break;
case "second": // Second call
result = new Bar[] { new Bar() }.ToList();
break;
}
return result;
};
Foo foo = sfoo.Instance;
Assert.AreEqual(0, foo.GetList("first").Count(), "First");
Assert.AreEqual(1, foo.GetList("second").Count(), "Second");
Assert.IsNull(foo.GetList("third"), "Third");
}
}
source to share