Guest User

Untitled

a guest
May 22nd, 2018
79
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 7.37 KB | None | 0 0
  1.     /// <summary>
  2.     /// An instantiated object of type <typeparamref name="TObject"/> with all its mocked constructor dependencies accessible.
  3.     /// </summary>
  4.     /// <typeparam name="TObject">Type of target object to create.</typeparam>
  5.     public class CreateObjectOfType<TObject> : IHideObjectMembers
  6.         where TObject : class
  7.     {
  8.         /// <summary>
  9.         /// Instance of TObject.
  10.         /// </summary>
  11.         public TObject Target { get; set; }
  12.  
  13.         /// <summary>
  14.         /// Use the static method BuildObjectWithDependencyMocks to construct instances.
  15.         /// </summary>
  16.         private CreateObjectOfType()
  17.         {
  18.             ParameterMocks = new List<IParameterMock>();
  19.         }
  20.  
  21.         /// <summary>
  22.         /// Builds an instance of type <typeparamref name="TTarget"/> with all dependencies mocked using <see cref="MockBehavior.Loose"/>.
  23.         /// </summary>
  24.         /// <typeparam name="TObject">Type of object created.</typeparam>
  25.         /// <returns>A container object containing the target along with the auto-mocked dependencies.</returns>
  26.         public static CreateObjectOfType<TObject> WithMocks(MockBehavior behavior)
  27.         {
  28.             var result = CreateConstructorParameterMocksAndInstance<TObject>(behavior);
  29.  
  30.             return new CreateObjectOfType<TObject>()
  31.             {
  32.                 ParameterMocks = result.Item1,
  33.                 Target = result.Item2
  34.             };
  35.         }
  36.  
  37.         /// <summary>
  38.         /// Builds an instance of type <typeparamref name="TTarget"/> with all dependencies mocked using <see cref="MockBehavior.Loose"/>.
  39.         /// </summary>
  40.         /// <typeparam name="TObject">Type of object created.</typeparam>
  41.         /// <returns>A container object containing the target along with the auto-mocked dependencies.</returns>
  42.         public static CreateObjectOfType<TObject> WithMocks()
  43.         {
  44.             return WithMocks(MockBehavior.Loose);
  45.         }
  46.  
  47.         /// <summary>
  48.         /// Builds an instance of type <typeparamref name="TTarget"/> with all dependencies mocked using <see cref="MockBehavior.Loose"/>.
  49.         /// </summary>
  50.         /// <typeparam name="TObject">Type of object created.</typeparam>
  51.         /// <returns>A container object containing the target along with the auto-mocked dependencies.</returns>
  52.         public static CreateObjectOfType<TObject> WithMocks<TDependency>(MockBehavior behavior)
  53.         {
  54.             //get the
  55.             var objectWithMocks = WithMocks<TObject>(MockBehavior.Loose);
  56.             return objectWithMocks;
  57.         }
  58.  
  59.         /// <summary>
  60.         /// Returns the mock used to implement <typeparamref name="TParameter"/>.
  61.         /// </summary>
  62.         /// <typeparam name="TParameter">Type of parameter being mocked.</typeparam>
  63.         /// <returns>A mock of <typeparamref name="TParameter"/>.</returns>
  64.         public Mock<TParameter> Mock<TParameter>()
  65.             where TParameter : class
  66.         {
  67.             return (ParameterMocks.Single(p => p is ParameterMock<TParameter>) as ParameterMock<TParameter>).Value;
  68.         }
  69.  
  70.         /// <summary>
  71.         /// Verifies that all verifiable expectations have been met.
  72.         /// </summary>
  73.         public void Verify()
  74.         {
  75.             foreach (var parameter in ParameterMocks)
  76.             {
  77.                 parameter.Mock.Verify();
  78.             }
  79.         }
  80.  
  81.         /// <summary>
  82.         /// Verifies that all verifiable expectations have been met, even ones not marked as verifiable.
  83.         /// </summary>
  84.         public void VerifyAll()
  85.         {
  86.             foreach (var parameter in ParameterMocks)
  87.             {
  88.                 parameter.Mock.VerifyAll();
  89.             }
  90.         }
  91.  
  92.         /// <summary>
  93.         /// Verifies that Mock of <typeparamref name="TParameter"/> expectations have been met.
  94.         /// </summary>
  95.         /// <typeparam name="TParameter">Type of parameter being mocked.</typeparam>
  96.         public void Verify<TTarget>()
  97.                 where TTarget : class
  98.         {
  99.             this.Mock<TTarget>().Verify(); //this code won't compile?
  100.             throw new NotImplementedException("MockedParameter<TObject>.Verify(); //this code won't compile?");
  101.         }
  102.  
  103.         /// <summary>
  104.         /// Verifies that Mock of <typeparamref name="TParameter"/> expectations have been met, even ones not marked as verifiable.
  105.         /// </summary>
  106.         /// <typeparam name="TParameter">Type of parameter being mocked.</typeparam>
  107.         public void VerifyAll<TTarget>()
  108.             where TTarget : class
  109.         {
  110.             this.Mock<TTarget>().VerifyAll();
  111.         }
  112.  
  113.         /// <summary>
  114.         /// Creates all the mocks required to instantiate a new instance of type <typeparam name="TTarget">.
  115.         /// </summary>
  116.         /// <param name="behavior">The <see cref="MockBehavior"/> to use by default.</param>
  117.         /// <param name="typeToUseAlternativeMockBehavior">Types which should use the alternative mock behavior to <paramref name="Behavior"/>.</param>
  118.         /// <remarks>By default the TTarget's constructor containing the most parameters is used.</remarks>
  119.         /// <example>
  120.         ///     Since there are only two options for MockBehavior, Strict and Loose. If you supply a default MockBehavior, any types supplied to typeToUseAlternativeMockBehavior will
  121.         ///     apply the alternative mocking behavior.
  122.         ///    
  123.         ///     All mocks are created using Loose behavior.
  124.         ///     CreateConstructorParameterMocksAndInstance(MockBehavior.Loose);
  125.         ///    
  126.         ///     TService and TAnotherService mocks are created using MockBehavior.Strict, all other mocks use MockBehavior.Loose.
  127.         ///     CreateConstructorParameterMocksAndInstance(MockBehavior.Loose, typeof(TService), typeof(TAnotherService));
  128.         /// </example>
  129.         private static Tuple<IList<IParameterMock>, TTarget> CreateConstructorParameterMocksAndInstance<TTarget>(MockBehavior defaultBehavior, params Type[] typesToUseAlternateBehavior)
  130.         {
  131.             var ctor = DefaultConstructorSelector<TTarget>();
  132.             var constructorParameters = ctor.GetParameters();
  133.             var alternateBehavior = (defaultBehavior == MockBehavior.Loose) ? MockBehavior.Strict : MockBehavior.Loose;
  134.  
  135.             // construct collection of Mock<ParameterType>
  136.             var mocks = from p in constructorParameters
  137.                                     let mockConstructor = typeof(Mock<>).MakeGenericType(p.ParameterType).GetConstructor(new Type[] { typeof(MockBehavior) })
  138.                                     let behavior = typesToUseAlternateBehavior.Contains(p.ParameterType) ? alternateBehavior : defaultBehavior
  139.                                     select new
  140.                                     {
  141.                                         Mock = mockConstructor.Invoke(new object[] { behavior }),
  142.                                         MockedType = p.ParameterType
  143.                                     };
  144.  
  145.             // construct collection ParameterMock<ParameterType>
  146.             var parameterMocks = from mock in mocks
  147.                                                      let parameterMockConstructor = typeof(ParameterMock<>).MakeGenericType(mock.MockedType).GetConstructor(System.Type.EmptyTypes)
  148.                                                      select parameterMockConstructor.Invoke(null) as IParameterMock;
  149.  
  150.             // extract instances from Mock via Mock.Object property
  151.             var parameters = new ArrayList();
  152.             foreach (var parameter in mocks)
  153.             {
  154.                 var parameterInstance = typeof(Mock<>).MakeGenericType(parameter.MockedType).GetProperties()[0].GetValue(parameter.Mock, null);
  155.                 parameters.Add(parameterInstance);
  156.             }
  157.  
  158.             var paramArray = parameters.ToArray();
  159.             var instance = (TTarget)ctor.Invoke(paramArray);
  160.  
  161.             return new Tuple<IList<IParameterMock>, TTarget>(parameterMocks.ToList(), instance);
  162.         }
  163.  
  164.         /// <summary>
  165.         /// Selects the constructor method.
  166.         /// </summary>
  167.         /// <typeparam name="TTarget">Type being constructed.</typeparam>
  168.         /// <returns>A constructor used to instantiate <typeparamref name="TTarget"/>.</returns>
  169.         private static ConstructorInfo DefaultConstructorSelector<TTarget>()
  170.         {
  171.             ConstructorInfo ctor = default(ConstructorInfo);
  172.             foreach (var c in typeof(TTarget).GetConstructors())
  173.             {
  174.                 if (ctor == null || ctor.GetParameters().Count() <= c.GetParameters().Count())
  175.                 {
  176.                     ctor = c;
  177.                 }
  178.             }
  179.             return ctor;
  180.         }
  181.  
  182.         private IList<IParameterMock> ParameterMocks { get; set; }
  183.  
  184.     }
Add Comment
Please, Sign In to add comment