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.

+3


source to share


1 answer


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");
    }
}

      

+4


source







All Articles