如何使用微软伪造在测试函数中多次调用的类填充

本文关键字:调用 填充 函数 微软 何使用 伪造 测试 | 更新日期: 2023-09-27 18:33:35

假设我有一个类,它有一个像这样的 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(( 调用返回不同的结果,比如分别包含一个和两个实体的列表。

为了进一步讨论,我想知道所谓的"假"和我们已经拥有的——"模拟"之间的区别

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

1.用Microsoft假货隔离被测代码

2.使用存根将应用程序的各个部分彼此隔离以进行单元测试

3.使用填充程序将应用程序与其他程序集隔离以进行单元测试

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

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

谢谢大家。

如何使用微软伪造在测试函数中多次调用的类填充

您可以在设置填充程序时通过捕获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");
    }
}