Ejemplo n.º 1
0
        /// <summary>
        /// Prepares the mocks, dependencies and the item under test.
        /// </summary>
        /// <exception cref="LeapingGorilla.Testing.Exceptions.NoItemUnderTestException">Thrown if the user has specified [Dependency]'s but there is no [ItemUnderTest]</exception>
        /// <exception cref="NoMatchingConstructorFoundException">Thrown if no constructor can be found on the [ItemUnderTest] that matches the number of [Dependency] fields/properties</exception>
        /// <exception cref="DependencyMismatchException">Thrown if a [Dependency] cannot be found for a constructor parameter when one is expected.</exception>
        /// <exception cref="NoItemUnderTestException">Thrown if there are fields/properties marked with [Dependency] but none with [ItemUnderTest]</exception>
        private void PrepareMocksDependenciesAndItemUnderTest()
        {
            // Create a fast accessor onto the test class
            var accessor = TypeAccessor.Create(GetType(), true);

            // Get and validate the item under test
            var itemUnderTest = GetPropertiesWithAttribute(typeof(ItemUnderTestAttribute)).Select(pi => new { Type = pi.PropertyType, pi.Name })
                                .Concat(GetFieldsWithAttribute(typeof(ItemUnderTestAttribute)).Select(pi => new { Type = pi.FieldType, pi.Name }))
                                .FirstOrDefault();

            // Create mocks and dependencies
            CreateManualDependencies();
            var dependencies = CreateAndAssignPropertiesOrFieldsWithAttribute(accessor, typeof(DependencyAttribute));

            dependencies.AddRange(CreateAndAssignPropertiesOrFieldsWithAttribute(accessor, typeof(NullDependencyAttribute)));

            CreateAndAssignPropertiesOrFieldsWithAttribute(accessor, typeof(MockAttribute));

            // It is invalid to have dependencies but no item under test
            if (itemUnderTest == null)
            {
                if (dependencies.Count > 0)
                {
                    throw new NoItemUnderTestException();
                }

                // No item under test but no dependencies. We can abort out of the rest of the setup
                return;
            }

            // Determine the correct constructor for the item under test. If we cant match one then error out
            var constructor = GetPreferredConstructor(itemUnderTest.Type, dependencies);

            if (constructor == null)
            {
                throw new NoMatchingConstructorFoundException(dependencies);
            }


            var parameters           = constructor.GetParameters();
            var constructorArguments = new object[parameters.Length];

            // Assign parameters. We remove them from the dependencies list as we go so we don't re-use dependencies in case of indirect (type only) matching
            for (int index = 0; index < parameters.Length; index++)
            {
                var param = parameters[index];
                var dep   = dependencies.FirstOrDefault(d => d.Name == param.Name && d.Type == param.ParameterType) ?? dependencies.FirstOrDefault(d => d.Type == param.ParameterType);

                if (dep == null)
                {
                    throw new DependencyMismatchException(param.ParameterType, param.Name, index, parameters);
                }

                dependencies.Remove(dep);
                constructorArguments[index] = dep.Value;
            }

            // Create the item under test and load it into the test class
            accessor[this, itemUnderTest.Name] = Activator.CreateInstance(itemUnderTest.Type, constructorArguments);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Creates a new ObjectReader instance for reading the supplied data
        /// </summary>
        /// <param name="type">The expected Type of the information to be read</param>
        /// <param name="source">The sequence of objects to represent</param>
        /// <param name="members">The members that should be exposed to the reader</param>
        public ObjectReader(Type type, IEnumerable source, params string[] members)
        {
            if (source == null)
            {
                throw new ArgumentOutOfRangeException("source");
            }



            bool allMembers = members == null || members.Length == 0;

            this.accessor = TypeAccessor.Create(type);
            if (accessor.GetMembersSupported)
            {
                var typeMembers = this.accessor.GetMembers();

                if (allMembers)
                {
                    members = new string[typeMembers.Count];
                    for (int i = 0; i < members.Length; i++)
                    {
                        members[i] = typeMembers[i].Name;
                    }
                }

                this.allowNull      = new BitArray(members.Length);
                this.effectiveTypes = new Type[members.Length];
                for (int i = 0; i < members.Length; i++)
                {
                    Type   memberType = null;
                    bool   allowNull  = true;
                    string hunt       = members[i];
                    foreach (var member in typeMembers)
                    {
                        if (member.Name == hunt)
                        {
                            if (memberType == null)
                            {
                                var tmp = member.Type;
                                memberType = Nullable.GetUnderlyingType(tmp) ?? tmp;

                                allowNull = !(memberType.IsValueType && memberType == tmp);

                                // but keep checking, in case of duplicates
                            }
                            else
                            {
                                memberType = null; // duplicate found; say nothing
                                break;
                            }
                        }
                    }
                    this.allowNull[i]      = allowNull;
                    this.effectiveTypes[i] = memberType ?? typeof(object);
                }
            }
            else if (allMembers)
            {
                throw new InvalidOperationException("Member information is not available for this type; the required members must be specified explicitly");
            }

            this.current     = null;
            this.memberNames = (string[])members.Clone();

            this.source = source.GetEnumerator();
        }