Login or Sign Up to become a member!
LessThanDot Sit Logo

LessThanDot

Desktop Developer

Less Than Dot is a community of passionate IT professionals and enthusiasts dedicated to sharing technical knowledge, experience, and assistance. Inside you will find reference materials, interesting technical discussions, and expert tips and commentary. Once you register for an account you will have immediate access to the forums and all past articles and commentaries.

LTD Social Sitings

Lessthandot twitter Lessthandot Linkedin Lessthandot friendfeed Lessthandot facebook Lessthandot rss

Note: Watch for social icons on posts by your favorite authors to follow their postings on these and other social sites.

Your profile

    Search

    XML Feeds

    Google Ads

    « Productive Programing With Pattern MatchingGit, TortoiseGit, Github and the rest »
    comments

    Introduction

    I use the Automocking feature of StructureMap quite a lot. But they only have support for Rhino Mocks and Moq. Now there is a new mocking framework, NSubstitute, and I would like to use that. But for that I needed an AutoMocker to take some of the work out of my hands. The StructureMap AutoMocker makes it easy for you to extend it.
    There are 2 ways you can extend the framework.

    1. You can fork the StructureMap code and add the Automocker to it and then work with you compiled fork. Perhaps even giving back to the StructureMap team what you made. Or you can just reference the binaries and go from there. I choose to do the first.

    The Tests

    First the test. This is what I want it to do when it works.

    1. using System;
    2. using System.Collections.Generic;
    3. using System.Linq;
    4. using System.Text;
    5. using NUnit.Framework;
    6. using StructureMap.AutoMocking;
    7. using NSubstitute;
    8.  
    9. namespace StructureMap.Testing.NSubstitute
    10. {
    11.     [TestFixture]
    12.     public class NSubstituteAutoMockerTester
    13.     {
    14.         [Test]
    15.         public void IfClassUnderTestReturnsAnObjectOfTypeTestClass()
    16.         {
    17.             var mocks = new NSubstituteAutoMocker<TestClass>();
    18.             var test = mocks.ClassUnderTest;
    19.             Assert.IsInstanceOfType(typeof(TestClass),test);
    20.         }
    21.  
    22.         [Test]
    23.         public void IfClassUnderTestIsNotNull()
    24.         {
    25.             var mocks = new NSubstituteAutoMocker<TestClass>();
    26.             var test = mocks.ClassUnderTest;
    27.             Assert.IsNotNull(test);
    28.         }
    29.  
    30.         [Test]
    31.         public void IfGetIClassUnderTestIsNotNull()
    32.         {
    33.             var mocks = new NSubstituteAutoMocker<TestClass>();
    34.             var test = mocks.ClassUnderTest;
    35.             Assert.IsNotNull(mocks.Get<ITestClass>());
    36.         }
    37.  
    38.         [Test]
    39.         public void IfGetITestClassIsSameAsClassUnderTestITestClass()
    40.         {
    41.             var mocks = new NSubstituteAutoMocker<TestClass>();
    42.             var test = mocks.ClassUnderTest;
    43.             Assert.AreSame(mocks.Get<ITestClass>(), test.TestClass1);
    44.         }
    45.  
    46.         [Test]
    47.         public void IfDependecyReturnsValueWhenSet()
    48.         {
    49.             var mocks = new NSubstituteAutoMocker<TestClass>();
    50.             var test = mocks.ClassUnderTest;
    51.             var itest = mocks.Get<ITestClass>();
    52.             itest.returnInt().Returns(3);
    53.             Assert.AreEqual(3, test.returnInt());
    54.         }
    55.        
    56.     }
    57.  
    58.     public class TestClass
    59.     {
    60.         private ITestClass _test;
    61.  
    62.         public ITestClass TestClass1
    63.         {
    64.             get { return _test; }
    65.         }
    66.  
    67.         public TestClass(ITestClass test)
    68.         {
    69.             _test = test;
    70.         }
    71.  
    72.         public int returnInt()
    73.         {
    74.             return _test.returnInt();
    75.         }
    76.     }
    77.  
    78.     public interface ITestClass
    79.     {
    80.         int returnInt();
    81.     }
    82. }

    The implementation

    You just need to add 3 files. The first inherits from AutoMocker<>

    1. using System;
    2. using System.Collections.Generic;
    3. using System.Linq;
    4. using System.Text;
    5.  
    6. namespace StructureMap.AutoMocking
    7. {
    8.     public class NSubstituteAutoMocker<TARGETCLASS> : AutoMocker<TARGETCLASS> where TARGETCLASS : class
    9.     {
    10.         public NSubstituteAutoMocker()
    11.         {
    12.             _serviceLocator = new NSubstituteServiceLocator();
    13.             _container = new AutoMockedContainer(_serviceLocator);
    14.         }
    15.     }
    16. }

    And that was very easy ;-).

    The second implements ServiceLocator.

    1. using System;
    2. using System.Collections.Generic;
    3. using System.Linq;
    4. using System.Text;
    5.  
    6. namespace StructureMap.AutoMocking
    7. {
    8.     class NSubstituteServiceLocator: ServiceLocator
    9.     {
    10.  
    11.         #region ServiceLocator Members
    12.  
    13.         private readonly NSubstituteFactory _substitutes = new NSubstituteFactory();
    14.  
    15.         public T Service<T>() where T : class
    16.         {
    17.             return (T)_substitutes.CreateMock(typeof(T));
    18.         }
    19.  
    20.         public object Service(Type serviceType)
    21.         {
    22.             return _substitutes.CreateMock(serviceType);
    23.         }
    24.  
    25.         public T PartialMock<T>(params object[] args) where T : class
    26.         {
    27.             return (T)_substitutes.CreateMock(typeof(T));
    28.         }
    29.  
    30.         #endregion
    31.     }
    32. }

    I'm not sure about PartialMock since I don't know if NSubstitute supports that.

    And the third one was the most difficult one.

    1. using System;
    2. using System.Reflection;
    3.  
    4. namespace StructureMap.AutoMocking
    5. {
    6.     public class NSubstituteFactory
    7.     {
    8.         private readonly Type mockOpenType;
    9.        
    10.         public NSubstituteFactory()
    11.         {
    12.             Assembly NSubstitute = Assembly.Load("NSubstitute");
    13.             mockOpenType = NSubstitute.GetType("NSubstitute.Substitute");
    14.             if (mockOpenType == null)
    15.                 throw new InvalidOperationException("Unable to find Type NSubstitute.Substitute in assembly " + NSubstitute.Location);
    16.         }
    17.  
    18.         public object CreateMock(Type type)
    19.         {
    20.             MethodInfo[] methods = mockOpenType.GetMethods();
    21.             foreach (MethodInfo method in methods)
    22.             {
    23.                 if (method.ContainsGenericParameters && method.GetGenericArguments().Length == 1)
    24.                 {
    25.                     Type[] genericArguments = new Type[] { type };
    26.                     MethodInfo generic = method.MakeGenericMethod(type);
    27.                     if (generic == null)
    28.                         throw new InvalidOperationException(
    29.                             "Unable to find method For<>() on MockRepository.");
    30.                     return generic.Invoke(null, new object[1] {null});
    31.                 }
    32.             }
    33.             return null;
    34.         }
    35.  
    36.     }
    37. }

    The automocked assembly holds no reference to NSubstitute but loads it dynamically so the user that implements the assembly must have a reference to NSubstitute. The big advantage of this approach is that you will not get versioning conflicts. The big disadvantage is that if they decide to rename methods it will no longer work.

    Conclusion

    It was fairly easy to make a new NSubstituteAutoMocker for StructureMap. Because it was Open source it was easy for me to look at what was already there and learn from it. I could have done the same when it was closed source but I would not have had the example and thus had to work out a lot of it myself.
    This probably needs some more work. But it does what I need it to do for now.

    About the Author

    User bio imageChristiaan is a forensic technician who programs on the side, although my function description says that I do IT-things for 90% of the time . I'm an avid VB.NET fan and I use lots of the ALT.Net techniques, like unit-testing, nhibernate, logging, IoC, ...
    Social SitingsTwitterLinkedInHomePageLTD RSS Feed
    Instapaper

    No feedback yet

    Leave a comment


    Your email address will not be revealed on this site.

    Your URL will be displayed.
    (Line breaks become <br />)
    (Name, email & website)
    (Allow users to contact you through a message form (your email will not be revealed.)