【问题标题】:How do I get shims for base classes using Microsoft Fakes?如何使用 Microsoft Fakes 获取基类的垫片?
【发布时间】:2013-02-16 23:08:56
【问题描述】:
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
   }
}

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

【问题讨论】:

  • 我也很好奇如何实现这一点。你有没有在其他地方得到任何答案?

标签: c# microsoft-fakes


【解决方案1】:

Parent 生成的类将有一个如下构造函数:ShimParent(Parent p)

您需要做的就是:

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

并在各个 Shim 上设置适当的值。

【讨论】:

  • 这应该是公认的答案。请参阅msdn.microsoft.com/en-us/library/hh549176.aspx 中的 基本成员 部分
  • 然后您必须使用您创建的parent 对象,并根据需要向下转换。
  • 您不需要使用父级。您可以使用子级,它会自动使用在父级上设置的任何内容。有关示例,请参阅文档 beluchin 参考。
【解决方案2】:

您必须在基类上声明它。最简单的方法是调用基类的 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 以确保正确清洁您的 shim。否则,您的其他单元测试也将获得您之前声明的返回值。 有关 ShimsContext 的信息可以在这里找到:http://msdn.microsoft.com/en-us/library/hh549176.aspx#ShimsContext

【讨论】:

    【解决方案3】:

    我已经根据以前的答案、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 属性的值。

    【讨论】:

      【解决方案4】:

      到目前为止,我认为没有一个建议的方法可行。经过大量的试验和错误,我想出了下面这个对我有用的代码。基本上,您必须定义一个初始化您的子类的委托,并在该委托中连接您的子类应继承的父 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";
                          }
                      };
                  };
              }
          }
      

      【讨论】:

        猜你喜欢
        • 2014-10-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-11-05
        • 1970-01-01
        • 2014-06-19
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多