Unit test of the "new" and "override" implementation in C#

No.of Views251
Bookmarked0 times
Downloads 
Votes0
By  Jv   On  23 Jul 2010 02:07:41
Tag : CSharp , How to
Ambiguity between the "new" and "override" keyword as misunderstood by many is removed with these unit tests.
emailbookmarkadd commentsprint

Images in this article missing? We recently lost them in a site migration. We're working to restore these as you read this. Should you need an image in an emergency, please contact us at info@codegain.com

 

Here is an interesting challenge - Unit testing the "new" and "override" keyword implementation.

Since, the "new" keyword was introduced to hide a base class implementation there has been a lot of arguments on how to actually show the execution of these methods in a polymorphic perspective.

Below is an example that solidly tests the classes and generates the necessary result.

// Class Under Test

using System;
using NUnit.Framework;
namespace NewAndOverrideTest
{
public class BaseClass
{
       protected BaseClass ob;
       public BaseClass(){}
 

      public virtual BaseClass OverrideMethod()
      {
            ob = new BaseClass();
            Console.WriteLine("Virtual from Base Class");
            return ob;
       }
}
public class DerivedClass : BaseClass
{
       public override BaseClass OverrideMethod()
       {  
            ob = new DerivedClass();
            Console.WriteLine("Override from DerivedClass Class");
            return ob;
        }
}
public class SecondDerivedClass : DerivedClass
{
        public new BaseClass OverrideMethod()
        {
             ob = new SecondDerivedClass();
             Console.WriteLine("New from SecondDerivedClass Class");
             return ob;
         }
}
public class ThirdDerivedClass : SecondDerivedClass
{
         public BaseClass OverrideMethod()
         {
              ob = new ThirdDerivedClass();
              Console.WriteLine("New from ThirdDerivedClass Class");
              return ob;
           }
}
}

// The NUnit Tests

using System;
using NUnit.Framework;
namespace NewAndOverrideTest
{
public class UnitTestOfNewAndOverride
{
          [TestFixture]
          public class TestNewOverride
          {
               private BaseClass baseClassObject;
               private DerivedClass derivedClassObject;
               private SecondDerivedClass secondDerivedClassObject;
          [SetUp]
          public void InitializeCUTObject()
          {
          }
          [Test]
          public void TestTheObjectCallingTheBaseMethod()
          {
               baseClassObject = new DerivedClass();
               Assert.That(baseClassObject.OverrideMethod(), Is.InstanceOf(typeof(DerivedClass)));
           }
           [Test]
           public void TestTheObjectCallingTheSecondDerivedMethod()
           {
                derivedClassObject = new SecondDerivedClass();
                Assert.That(derivedClassObject.OverrideMethod(), Is.InstanceOf(typeof(SecondDerivedClass)));
            }

The 2nd test, "TestTheObjectCallingTheSecondDerivedMethod" fails because the instance is pointing to SecondDerivedClass whose "OverrideMethod" is actually a "new" implementation. This causes the execution engine not to look for polymorphic behavior but to call the object instance type's implementation, ie, the DerivedClass OverrideMethod.

The test will pass if Assert statement is changed to query for "InstanceOf(typeof(DerivedClass)".

Below is the same test with Rhino Mock. I have used Rhino Mock just to demonstrate mock testing, with Rhino Mock, in the unit tests. It is a rather contrived example but it serves its purpose.

Rhino Mock 2.6, NUnit 2.5 and .net 2.0 are required to execute the tests and the code.


// The Interface

using System;

namespace NewAndOverrideTest
{
          public interface INewOverride
          {
               void NewMethod();
               Object OverrideMethod();
           }
}

// The NUnit Test Class
using System;
using NUnit.Framework;
using Rhino.Mocks;
namespace NewAndOverrideTest
{
          [TestFixture]
          public class TestNewOverride
          {
               private BaseClass baseClassObject;
               private DerivedClass derivedClassObject;
               private SecondDerivedClass secondDerivedClassObject;
               private ThirdDerivedClass thirdDerivedClassObject;
               private MockRepository mockObject;
               private INewOverride interfaceObject;
           [SetUp]
          public void InitializeCUTObject()
          {
                mockObject = new MockRepository();
                interfaceObject = (INewOverride)mockObject.CreateMock(typeof(INewOverride));
           }
           [Test]
           public void TestTheObjectCallingTheBaseMethod()
           {
                Expect.Call(interfaceObject.OverrideMethod()).Return(typeof(DerivedClass) as object);
                mockObject.Record();
                baseClassObject = new DerivedClass();
                baseClassObject.NewMethod();
                mockObject.ReplayAll();
                Assert.That(interfaceObject.OverrideMethod(), Is.InstanceOf(typeof(object)));
                mockObject.Verify(interfaceObject);
            }
            [Test]
            public void TestTheObjectCallingTheSecondDerivedMethod()
            {
                 Expect.Call(interfaceObject.OverrideMethod()).Return(typeof(SecondDerivedClass) as object);
                 mockObject.Record();
                 derivedClassObject = new SecondDerivedClass();
                 derivedClassObject.NewMethod();
                 mockObject.Replay(interfaceObject);
                 Assert.That(interfaceObject.OverrideMethod(), Is.InstanceOf(typeof(object)));
                 mockObject.Verify(interfaceObject);
              }
              [Test]
              [ExpectedException(typeof(NullReferenceException))]
              public void TestTheObjectCallingTheThirdDerivedMethod()
              {
                  Expect.Call(interfaceObject.OverrideMethod()).Throw(new NullReferenceException());
                  mockObject.Record();
                  thirdDerivedClassObject = new ThirdDerivedClass();
                  //thirdDerivedClassObject.NewMethod();
                  mockObject.Replay(interfaceObject);
                  Assert.That(interfaceObject.OverrideMethod(), Is.InstanceOf(typeof(Object)));
                  mockObject.Verify(interfaceObject);
               }
}
}

// The CUT (Class Under Test)
using System;

namespace NewAndOverrideTest
{
               public class BaseClass:INewOverride
               {
                   protected BaseClass ob;
               public BaseClass(){ }
               public void NewMethod()
               {
                   ob = new BaseClass();
                   Console.WriteLine("Base Class");
                }
               public Object OverrideMethod()
               {
                   Console.WriteLine("Virtual from Base Class");
                   return ob as object;
                }
               }
                public class DerivedClass : BaseClass
                {
                public void NewMethod()
                {
                    ob = new DerivedClass();
                    Console.WriteLine("DerivedClass Class");
                 }
               public Object OverrideMethod()
               {
                    Console.WriteLine("Override from DerivedClass Class");
                    return ob as object;
                }
              }
              public class SecondDerivedClass : DerivedClass
              {
              public void NewMethod()
              {
                    ob = new SecondDerivedClass();
                    Console.WriteLine("SecondDerivedClass Class");
               }
               public new Object OverrideMethod()
               {
                     Console.WriteLine("Override from SecondDerivedClass Class");
                    return ob;
                }
              }
               public class ThirdDerivedClass : SecondDerivedClass
               {
               public void NewMethod()
               {
                     ob = new SecondDerivedClass();
                     Console.WriteLine("ThirdDerivedClass Class");
                }
               public Object OverrideMethod()
               {
                    Console.WriteLine("Override from ThirdDerivedClass Class");
                     return ob as object;
                }
              }
}

 
Sign Up to vote for this article
 
About Author
 
Jv
Occupation-
Company-JK Technosoft Ltd., Noida, India
Member Type-Fresh
Location-India
Joined date-23 Jul 2010
Home Page-
Blog Page-http://ravichandranjv.blogspot.com
 
 
Other popularSectionarticles
    Comments
    There is no comments for this articles.
    Leave a Reply
    Title:
    Display Name:
    Email:
    (not display in page for the security purphase)
    Website:
    Message:
    Please refresh your screen using Ctrl+F5
    If you can't read this number refresh your screen
    Please input the anti-spam code that you can read in the image.
    ^ Scroll to Top