如何使用Microsoft Fakes为基类获取填充程序?

时间:2013-02-16 23:08:57

标签: c# microsoft-fakes

class Parent{
   public string Name{ get; set; }
}

class Child :Parent{
   public string  address{ get; set; }
}

[TestClass]
class TestClass{
   [TestMethod]
   public void TestMethod()
   {
      var c = new Fakes.Child();
      c.addressGet = "foo"; // I can see that
      c.NameGet = "bar"; // This DOES NOT exists
   }
}

如何在上面的代码示例中设置“名称”?

4 个答案:

答案 0 :(得分:13)

Parent生成的类将包含一个类似于ShimParent(Parent p)的构造函数。

您需要做的就是:

var child = new ShimChild();
var parent = new ShimParent(child);

并在相应的Shim上设置适当的值。

答案 1 :(得分:12)

您必须在基类上声明它。最简单的方法是将基类调用为AllInstances属性:

[TestClass]
public class UnitTest1
{
    [TestMethod]
    public void TestMethod1()
    {
        ClassLibrary1.Child myChild = new ClassLibrary1.Child();

        using (ShimsContext.Create())
        {
            ClassLibrary1.Fakes.ShimChild.AllInstances.addressGet = (instance) => "foo";
            ClassLibrary1.Fakes.ShimParent.AllInstances.NameGet = (instance) => "bar";

            Assert.AreEqual("foo", myChild.address);
            Assert.AreEqual("bar", myChild.Name);
        }

    }
}

也总是尝试添加ShimsContext以确保正确清洁垫片。否则,您的其他单元测试也将获得您之前声明的返回值。 有关ShimsContext的信息,请访问:http://msdn.microsoft.com/en-us/library/hh549176.aspx#ShimsContext

答案 2 :(得分:2)

我根据以前的答案,Microsoft文档和我自己的实验整理了一个解决方案。我还更改了TestMethod以显示我将如何实际使用它进行测试。注意:我没有编译这个特定的代码,所以如果它不能正常工作,我会道歉。

[TestClass]
class TestClass
{
   [TestMethod]
   public void TestMethod()
   {
      using (ShimsContext.Create())
      {
         Child child = CreateShimChild("foo", "bar");

         Assert.AreEqual("foo", child.address);  // Should be true
         Assert.AreEqual("bar", child.Name);     // Should be true
      }
   }

   private ShimChild CreateShimChild(string foo, string bar)
   {
      // Create ShimChild and make the property "address" return foo
      ShimChild child = new ShimChild() { addressGet = () => foo };

      // Here's the trick: Create a ShimParent (giving it the child)
      // and make the property "Name" return bar;
      new ShimParent(child) { NameGet = () => bar };

      return child;
   }
}

我不知道返回的孩子怎么知道它的Name应该返回“bar”,但确实如此!如您所见,您甚至不需要将ShimParent保存在任何地方;它只是为了指定Name属性的值而创建的。

答案 3 :(得分:0)

到目前为止,所建议的方法都不适用于我看来。经过大量的反复试验后,我提出了以下代码,对我有用。基本上,您必须定义一个初始化您的子类的委托,并在该委托中连接您的子类应继承的父级的Shim。

public void TestMethod()
    {
        //var c = new Fakes.Child();
        //c.addressGet = "foo"; // I can see that
        //c.NameGet = "bar"; // This DOES NOT exists

        using (ShimsContext.Create())
        {
            ShimChild childShim = null;
            ShimChild.Constructor = (@this) =>
            {

                childShim = new ShimChild(@this);
                // the below code now defines a ShimParent object which will be used by the ShimChild object I am creating here
                new ShimParent()
                {
                    NameSetString = (value) =>
                    {
                        //do stuff here
                    },
                    NameGet = () =>
                    {
                        return "name";
                    }
                };
            };
        }
    }