如何使用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 } }
如何在上面的代码示例中设置“名称”?
为Parent
生成的类将具有如下构造函数: ShimParent(Parent p)
。
您需要做的就是:
var child = new ShimChild(); var parent = new ShimParent(child);
并在相应的垫片上设置适当的值。
你必须在基类上声明它。 最简单的方法是将基类调用为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以确保正确清洁垫片。 否则,您的其他unit testing也将获得您之前声明的返回值。 有关ShimsContext的信息可以在这里找到: http : //msdn.microsoft.com/en-us/library/hh549176.aspx#ShimsContext
我根据以前的答案,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
属性的值而创建的。
到目前为止,所建议的方法都不适用于我的观点。 经过大量的反复试验后,我提出了以下代码,对我有用。 基本上,您必须定义一个初始化您的子类的委托,并在该委托中连接您的子类应inheritance的父级的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"; } }; }; } }