19
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
   }
}

How can I set the "name" in the above code sample?

kalrashi
  • 1,423
  • 3
  • 14
  • 15

4 Answers4

15

The generated class for Parent will have a constructor that looks like: ShimParent(Parent p).

All you need to do is:

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

And set the appropriate values on the respective Shim's.

Jesus is Lord
  • 14,971
  • 11
  • 66
  • 97
  • 5
    This should be the accepted answer. See the _Base members_ section in http://msdn.microsoft.com/en-us/library/hh549176.aspx – beluchin Mar 28 '14 at 10:50
  • You then have to use the `parent` object you created, downcasting it as necessary. – Dov Sep 12 '14 at 19:22
  • You don't need to use the parent. You can use child and it will automatically use anything that was set on parent. See the documentation beluchin references for an example. – Erica Sep 29 '14 at 21:05
12

You'll have to declare it on the base class. The easiest way is to call the base class its AllInstances property:

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

    }
}

Also always try to add the ShimsContext to ensure the proper cleaning of your shim. Otherwise your other unit tests will also get the values returned that you have declared before. Information on ShimsContext can be found here: http://msdn.microsoft.com/en-us/library/hh549176.aspx#ShimsContext

smeel
  • 123
  • 6
2

I've put together a solution based on previous answers, the Microsoft documentation, and my own experimentation. I've also changed the TestMethod a bit to show how I would actually use it for testing. Note: I haven't compiled this specific code, so I apologize if it doesn't work as is.

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

I have no idea how the returned child knows that its Name should return "bar", but it does! As you can see, you don't even need to save the ShimParent anywhere; it's only created in order to specify the value for the Name property.

redcurry
  • 2,381
  • 2
  • 24
  • 38
0

None of the suggested approaches so far would work in my opinion. After a lot of trial and error I have come up with this below code which worked for me. Basically you will have to define a delegate that initializes your child class and within that delegate you hookup a Shim of parent that your child class should inherit from.

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";
                    }
                };
            };
        }
    }
Nikhil
  • 3,304
  • 1
  • 25
  • 42