C# 如何使用Microsoft Fakes获取基类的垫片?

C# 如何使用Microsoft Fakes获取基类的垫片?,c#,microsoft-fakes,C#,Microsoft Fakes,如何在上面的代码示例中设置“name”?您必须在基类中声明它。最简单的方法是调用基类的AllInstances属性: class Parent{ public string Name{ get; set; } } class Child :Parent{ public string address{ get; set; } } [TestClass] class TestClass{ [TestMethod] public void TestMethod()

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

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

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
   }
}
还要始终尝试添加ShimsContext,以确保正确清洁垫片。否则,您的其他单元测试也将获得您之前声明的返回值。
有关ShimsContext的信息可在此处找到:

父级
生成的类将有一个类似于以下内容的构造函数:
ShimsParent(父级p)

您需要做的只是:

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

    }
}

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

我认为,目前为止建议的方法都不起作用。经过大量的尝试和错误,我已经想出了下面的代码,它为我工作。基本上,您必须定义一个委托来初始化您的子类,并在该委托中连接一个父类的垫片,您的子类应该从该垫片继承

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

我已经根据以前的答案、Microsoft文档和我自己的实验提出了一个解决方案。我还对
TestMethod
做了一些修改,以展示如何实际使用它进行测试。注意:我还没有编译这个特定的代码,所以如果它不能正常工作,我很抱歉

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

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

我也很好奇如何实现这一点。你在别的地方得到答案了吗?这应该是公认的答案。请参阅中的“基本成员”部分,然后您必须使用您创建的
父对象,根据需要向下转换它。您不需要使用父对象。您可以使用child,它将自动使用在parent上设置的任何内容。有关示例,请参阅文档《beluchin参考》。
[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;
   }
}