object IProxyFactory.GenerateProxy(ICallRouter callRouter, Type typeToProxy, Type[] additionalInterfaces, object[] constructorArguments)
        {
            // TODO:
            //  * new type MockCtorPlaceholder in elevated assy
            //  * generate new empty ctor that takes MockCtorPlaceholder in all mocked types
            //  * support ctor params. throw if foudn and not ForPartsOf. then ForPartsOf determines which ctor we use.
            //  * have a note about static ctors. because they are special, and do not support disposal, can't really mock them right.
            //    best for user to do mock/unmock of static ctors manually (i.e. move into StaticInit/StaticDispose and call directly from test code)

            object proxy;
            var    substituteConfig = ElevatedSubstitutionContext.TryGetSubstituteConfig(callRouter);

            if (typeToProxy.IsInterface || substituteConfig == null)
            {
                proxy = m_DefaultProxyFactory.GenerateProxy(callRouter, typeToProxy, additionalInterfaces, constructorArguments);
            }
            else if (typeToProxy == typeof(SubstituteStatic.Proxy))
            {
                if (additionalInterfaces != null && additionalInterfaces.Any())
                {
                    throw new SubstituteException("Cannot substitute interfaces as static");
                }
                if (constructorArguments.Length != 1)
                {
                    throw new SubstituteException("Unexpected use of SubstituteStatic.For");
                }

                // the type we want comes from SubstituteStatic.For as a single ctor arg
                var actualType = (Type)constructorArguments[0];

                proxy = CreateStaticProxy(actualType, callRouter);
            }
            else
            {
                // requests for additional interfaces on patched types cannot be done at runtime. elevated mocking can't,
                // by definition, go through a runtime dynamic proxy generator that could add such things.
                if (additionalInterfaces.Any())
                {
                    throw new SubstituteException("Cannot add interfaces at runtime to patched types");
                }

                if (substituteConfig == SubstituteConfig.OverrideAllCalls)
                {
                    // overriding all calls includes the ctor, so it makes no sense for the user to pass in ctor args
                    if (constructorArguments.Any())
                    {
                        throw new SubstituteException("Do not pass ctor args when substituting with elevated mocks (or did you mean to use ForPartsOf?)");
                    }

                    // but we use a ctor arg to select the special empty ctor that we patched in
                    constructorArguments = k_MockedCtorParams;
                }

                proxy = Activator.CreateInstance(typeToProxy, constructorArguments);
                GetRouterField(typeToProxy).SetValue(proxy, callRouter);
            }

            return(proxy);
        }
        public static IDisposable AutoHook()
        {
            var hookedContext = SubstitutionContext.Current;
            var thisContext   = new ElevatedSubstitutionContext(hookedContext);

            SubstitutionContext.Current = thisContext;

            return(new DelegateDisposable(() =>
            {
                if (SubstitutionContext.Current != thisContext)
                {
                    throw new SubstituteException("Unexpected hook in place of ours");
                }
                SubstitutionContext.Current = hookedContext;
            }));
        }
示例#3
0
        public static IDisposable AutoHook(string assemblyLocation)
        {
            var hookedContext = SubstitutionContext.Current;
            var thisContext   = new ElevatedSubstitutionContext(hookedContext);

            SubstitutionContext.Current = thisContext;

            // TODO: return a new IDisposable class that also contains the list of patch results, then in caller verify that against expected (don't want to go too wide)

            var patchAllDependentAssemblies = ElevatedWeaver.PatchAllDependentAssemblies(
                new NPath(assemblyLocation), PatchOptions.PatchTestAssembly).ToList();

            return(new DelegateDisposable(() =>
            {
                if (SubstitutionContext.Current != thisContext)
                {
                    throw new SubstituteException("Unexpected hook in place of ours");
                }
                SubstitutionContext.Current = hookedContext;
            }));
        }