- 
                Notifications
    You must be signed in to change notification settings 
- Fork 277
Closed
Description
Describe the bug
NSubstitute/Castle proxy fails to create a substitute for a concrete class that derives from an abstract class and virtual members.
To Reproduce
Here's an example of what I am talking about:
Setup classes
namespace TestNSubstituteBS
{
    public abstract class AbstractIOContext
    {
        public abstract IDirectoryInfo CreateDirectoryInfo();
    }
}namespace TestNSubstituteBS
{
    public class ConcreteIOContext : AbstractIOContext
    {
        public override XDirectoryInfo CreateDirectoryInfo() => new XDirectoryInfo();
    }
}namespace TestNSubstituteBS
{
    public class XDirectoryInfo : IDirectoryInfo { }
}namespace TestNSubstituteBS
{
    public interface IDirectoryInfo { }
}Test code:
namespace TestNSubstituteBS.Tests
{
    [TestClass()]
    public class AbstractFactoryTests
    {
        [TestMethod]
        public void CreateTest()
        {
            var a = Substitute.For<ConcreteIOContext>(); // <--------------- fails here
            a.CreateDirectoryInfo().Returns(new XDirectoryInfo());
        }
    }
}Running the above returns this error message...
Test method TestNSubstituteBS.Tests.AbstractFactoryTests.CreateTest threw exception: 
System.TypeLoadException: Return type in method 'Castle.Proxies.ConcreteIOContextProxy.CreateDirectoryInfo()' on type 'Castle.Proxies.ConcreteIOContextProxy' from assembly 'DynamicProxyGenAssembly2, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' is not compatible with base type method 'TestNSubstituteBS.ConcreteIOContext.CreateDirectoryInfo()'.and stack trace...
  Stack Trace: 
TypeBuilder.CreateTypeNoLock()
TypeBuilder.CreateTypeInfo()
AbstractTypeEmitter.BuildType()
BaseClassProxyGenerator.GenerateType(String name, INamingScope namingScope)
<>c__DisplayClass13_0.<GetProxyType>b__0(CacheKey cacheKey)
SynchronizedDictionary`2.GetOrAdd(TKey key, Func`2 valueFactory)
BaseProxyGenerator.GetProxyType()
DefaultProxyBuilder.CreateClassProxyType(Type classToProxy, Type[] additionalInterfacesToProxy, ProxyGenerationOptions options)
ProxyGenerator.CreateClassProxyType(Type classToProxy, Type[] additionalInterfacesToProxy, ProxyGenerationOptions options)
ProxyGenerator.CreateClassProxy(Type classToProxy, Type[] additionalInterfacesToProxy, ProxyGenerationOptions options, Object[] constructorArguments, IInterceptor[] interceptors)
CastleDynamicProxyFactory.CreateProxyUsingCastleProxyGenerator(Type typeToProxy, Type[] additionalInterfaces, Object[] constructorArguments, IInterceptor[] interceptors, ProxyGenerationOptions proxyGenerationOptions)
CastleDynamicProxyFactory.GenerateTypeProxy(ICallRouter callRouter, Type typeToProxy, Type[] additionalInterfaces, Object[] constructorArguments)
CastleDynamicProxyFactory.GenerateProxy(ICallRouter callRouter, Type typeToProxy, Type[] additionalInterfaces, Object[] constructorArguments)
SubstituteFactory.Create(Type[] typesToProxy, Object[] constructorArguments, Boolean callBaseByDefault)
SubstituteFactory.Create(Type[] typesToProxy, Object[] constructorArguments)
Substitute.For(Type[] typesToProxy, Object[] constructorArguments)
Substitute.For[T](Object[] constructorArguments)
AbstractFactoryTests.CreateTest() line 18Expected behaviour
Preferibly, that it works. Otherwise, an error message about how much of an idiot I am.
Environment:
- NSubstitute version: 5.0.0
- NSubstitute.Analyzers version: 1.0.16
- Platform: .NET 6.0 Windows
Additional context
This occurs for Substitute.For<>() and Substitute.ForPartsOf<>().
Metadata
Metadata
Assignees
Labels
No labels