Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /// <summary>
- /// An instantiated object of type <typeparamref name="TObject"/> with all its mocked constructor dependencies accessible.
- /// </summary>
- /// <typeparam name="TObject">Type of target object to create.</typeparam>
- public class CreateObjectOfType<TObject> : IHideObjectMembers
- where TObject : class
- {
- /// <summary>
- /// Instance of TObject.
- /// </summary>
- public TObject Target { get; set; }
- /// <summary>
- /// Use the static method BuildObjectWithDependencyMocks to construct instances.
- /// </summary>
- private CreateObjectOfType()
- {
- ParameterMocks = new List<IParameterMock>();
- }
- /// <summary>
- /// Builds an instance of type <typeparamref name="TTarget"/> with all dependencies mocked using <see cref="MockBehavior.Loose"/>.
- /// </summary>
- /// <typeparam name="TObject">Type of object created.</typeparam>
- /// <returns>A container object containing the target along with the auto-mocked dependencies.</returns>
- public static CreateObjectOfType<TObject> WithMocks(MockBehavior behavior)
- {
- var result = CreateConstructorParameterMocksAndInstance<TObject>(behavior);
- return new CreateObjectOfType<TObject>()
- {
- ParameterMocks = result.Item1,
- Target = result.Item2
- };
- }
- /// <summary>
- /// Builds an instance of type <typeparamref name="TTarget"/> with all dependencies mocked using <see cref="MockBehavior.Loose"/>.
- /// </summary>
- /// <typeparam name="TObject">Type of object created.</typeparam>
- /// <returns>A container object containing the target along with the auto-mocked dependencies.</returns>
- public static CreateObjectOfType<TObject> WithMocks()
- {
- return WithMocks(MockBehavior.Loose);
- }
- /// <summary>
- /// Builds an instance of type <typeparamref name="TTarget"/> with all dependencies mocked using <see cref="MockBehavior.Loose"/>.
- /// </summary>
- /// <typeparam name="TObject">Type of object created.</typeparam>
- /// <returns>A container object containing the target along with the auto-mocked dependencies.</returns>
- public static CreateObjectOfType<TObject> WithMocks<TDependency>(MockBehavior behavior)
- {
- //get the
- var objectWithMocks = WithMocks<TObject>(MockBehavior.Loose);
- return objectWithMocks;
- }
- /// <summary>
- /// Returns the mock used to implement <typeparamref name="TParameter"/>.
- /// </summary>
- /// <typeparam name="TParameter">Type of parameter being mocked.</typeparam>
- /// <returns>A mock of <typeparamref name="TParameter"/>.</returns>
- public Mock<TParameter> Mock<TParameter>()
- where TParameter : class
- {
- return (ParameterMocks.Single(p => p is ParameterMock<TParameter>) as ParameterMock<TParameter>).Value;
- }
- /// <summary>
- /// Verifies that all verifiable expectations have been met.
- /// </summary>
- public void Verify()
- {
- foreach (var parameter in ParameterMocks)
- {
- parameter.Mock.Verify();
- }
- }
- /// <summary>
- /// Verifies that all verifiable expectations have been met, even ones not marked as verifiable.
- /// </summary>
- public void VerifyAll()
- {
- foreach (var parameter in ParameterMocks)
- {
- parameter.Mock.VerifyAll();
- }
- }
- /// <summary>
- /// Verifies that Mock of <typeparamref name="TParameter"/> expectations have been met.
- /// </summary>
- /// <typeparam name="TParameter">Type of parameter being mocked.</typeparam>
- public void Verify<TTarget>()
- where TTarget : class
- {
- this.Mock<TTarget>().Verify(); //this code won't compile?
- throw new NotImplementedException("MockedParameter<TObject>.Verify(); //this code won't compile?");
- }
- /// <summary>
- /// Verifies that Mock of <typeparamref name="TParameter"/> expectations have been met, even ones not marked as verifiable.
- /// </summary>
- /// <typeparam name="TParameter">Type of parameter being mocked.</typeparam>
- public void VerifyAll<TTarget>()
- where TTarget : class
- {
- this.Mock<TTarget>().VerifyAll();
- }
- /// <summary>
- /// Creates all the mocks required to instantiate a new instance of type <typeparam name="TTarget">.
- /// </summary>
- /// <param name="behavior">The <see cref="MockBehavior"/> to use by default.</param>
- /// <param name="typeToUseAlternativeMockBehavior">Types which should use the alternative mock behavior to <paramref name="Behavior"/>.</param>
- /// <remarks>By default the TTarget's constructor containing the most parameters is used.</remarks>
- /// <example>
- /// Since there are only two options for MockBehavior, Strict and Loose. If you supply a default MockBehavior, any types supplied to typeToUseAlternativeMockBehavior will
- /// apply the alternative mocking behavior.
- ///
- /// All mocks are created using Loose behavior.
- /// CreateConstructorParameterMocksAndInstance(MockBehavior.Loose);
- ///
- /// TService and TAnotherService mocks are created using MockBehavior.Strict, all other mocks use MockBehavior.Loose.
- /// CreateConstructorParameterMocksAndInstance(MockBehavior.Loose, typeof(TService), typeof(TAnotherService));
- /// </example>
- private static Tuple<IList<IParameterMock>, TTarget> CreateConstructorParameterMocksAndInstance<TTarget>(MockBehavior defaultBehavior, params Type[] typesToUseAlternateBehavior)
- {
- var ctor = DefaultConstructorSelector<TTarget>();
- var constructorParameters = ctor.GetParameters();
- var alternateBehavior = (defaultBehavior == MockBehavior.Loose) ? MockBehavior.Strict : MockBehavior.Loose;
- // construct collection of Mock<ParameterType>
- var mocks = from p in constructorParameters
- let mockConstructor = typeof(Mock<>).MakeGenericType(p.ParameterType).GetConstructor(new Type[] { typeof(MockBehavior) })
- let behavior = typesToUseAlternateBehavior.Contains(p.ParameterType) ? alternateBehavior : defaultBehavior
- select new
- {
- Mock = mockConstructor.Invoke(new object[] { behavior }),
- MockedType = p.ParameterType
- };
- // construct collection ParameterMock<ParameterType>
- var parameterMocks = from mock in mocks
- let parameterMockConstructor = typeof(ParameterMock<>).MakeGenericType(mock.MockedType).GetConstructor(System.Type.EmptyTypes)
- select parameterMockConstructor.Invoke(null) as IParameterMock;
- // extract instances from Mock via Mock.Object property
- var parameters = new ArrayList();
- foreach (var parameter in mocks)
- {
- var parameterInstance = typeof(Mock<>).MakeGenericType(parameter.MockedType).GetProperties()[0].GetValue(parameter.Mock, null);
- parameters.Add(parameterInstance);
- }
- var paramArray = parameters.ToArray();
- var instance = (TTarget)ctor.Invoke(paramArray);
- return new Tuple<IList<IParameterMock>, TTarget>(parameterMocks.ToList(), instance);
- }
- /// <summary>
- /// Selects the constructor method.
- /// </summary>
- /// <typeparam name="TTarget">Type being constructed.</typeparam>
- /// <returns>A constructor used to instantiate <typeparamref name="TTarget"/>.</returns>
- private static ConstructorInfo DefaultConstructorSelector<TTarget>()
- {
- ConstructorInfo ctor = default(ConstructorInfo);
- foreach (var c in typeof(TTarget).GetConstructors())
- {
- if (ctor == null || ctor.GetParameters().Count() <= c.GetParameters().Count())
- {
- ctor = c;
- }
- }
- return ctor;
- }
- private IList<IParameterMock> ParameterMocks { get; set; }
- }
Add Comment
Please, Sign In to add comment