如何使用微软假货来修补在测试函数中多次调用的类

时间:2014-12-08 11:50:44

标签: c# asp.net .net unit-testing microsoft-fakes

假设我有一个类,它有一个像这样的GetList():

public class Foo
{
    public List<Bar> GetList(string para);
}

测试的功能就像

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
    }
}

在我的测试方法中,我使用ShimFoo.AllInstance.GetList来填充GetList()。无论奇怪的业务和调用逻辑如何,我的问题是我如何才能进行第一次GetList()调用,第二次GetListh()调用返回不同的结果,比如分别包含一个和两个实体的列表。

为了进一步讨论,我想知道所谓的&#34;假&#34;以及我们已经拥有的东西 - &#34; mock&#34;

我已经阅读了关于MS Fake的三篇官方文章:

1。Isolating Code Under Test with Microsoft Fakes

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

但我还没有找到可以按照上述原则做的事情的指南。

我已经了解到行为验证可以在模拟测试中完成,有很多框架可以实现这一点(比如谷歌模拟)。我可以定义mock类在第一次/第二次/第三次调用时的工作方式,我可以设置一个序列来严格限制mock类。我想知道MS Fakes是否可以做同样的事情。

谢谢你们。

1 个答案:

答案 0 :(得分:7)

您可以通过在设置垫片时捕获int变量来保持呼叫计数器。

[TestMethod]
public void TestMethod1()
{
    using(ShimsContext.Create()) {
        int counter = 0; // define the int outside of the delegate to capture it's 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");
    }
}

或者您可以检查传递的参数并相应地调整结果。

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