-
-
Notifications
You must be signed in to change notification settings - Fork 826
Description
Unfortunately, this bug report is a little confusing, as I have tried multiple times to create a small reproducible example, but I am unable to.
I'm trying to make a mock of the Azure BlockBlobClient
This works fine, I can easily execute
var clientMock = new Mock<BlockBlobClient>();
var obj = clientMock.Object;
However, if I subclass the BlockBlobClient, everything goes wrong, even if the subclass does nothing.
[Fact]
public void ShouldBeAbleToSubclass()
{
// Arrange
var clientMock = new Mock<TestBlockBlobClient>();
var obj = clientMock.Object;
}
}
public class TestBlockBlobClient : BlockBlobClient
{
}I then get the following error:
Error Message:
System.ArgumentException : Type to mock must be an interface, a delegate, or a non-sealed, non-static class.
---- System.TypeLoadException : Method 'get_Pipeline' on type 'Castle.Proxies.TestBlockBlobClientProxy' from assembly 'DynamicProxyGenAssembly2, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' is overriding a method that is not visible from that assembly.
Stack Trace:
at Moq.CastleProxyFactory.CreateProxy(Type mockType, IInterceptor interceptor, Type[] interfaces, Object[] arguments)
at Moq.Mock`1.InitializeInstance()
at Moq.Mock`1.OnGetObject()
at Moq.Mock.get_Object()
at Moq.Mock`1.get_Object()
at AIP.Shared.Test.BlockBlobClientTests.ShouldBeAbleToSubclass() in /home/geewee/programming/OAI/Shared.Test/BlockBlobClientTests.cs:line 91
----- Inner Stack Trace -----
at System.Reflection.Emit.TypeBuilder.CreateTypeNoLock()
at System.Reflection.Emit.TypeBuilder.CreateTypeInfo()
at Castle.DynamicProxy.Generators.Emitters.AbstractTypeEmitter.CreateType(TypeBuilder type)
at Castle.DynamicProxy.Generators.Emitters.AbstractTypeEmitter.BuildType()
at Castle.DynamicProxy.Generators.ClassProxyGenerator.GenerateType(String name, Type[] interfaces, INamingScope namingScope)
at Castle.DynamicProxy.Generators.ClassProxyGenerator.<>c__DisplayClass1_0.<GenerateCode>b__0(String n, INamingScope s)
at Castle.DynamicProxy.Generators.BaseProxyGenerator.<>c__DisplayClass33_0.<ObtainProxyType>b__0(CacheKey _)
at Castle.Core.Internal.SynchronizedDictionary`2.GetOrAdd(TKey key, Func`2 valueFactory)
at Castle.DynamicProxy.Generators.BaseProxyGenerator.ObtainProxyType(CacheKey cacheKey, Func`3 factory)
at Castle.DynamicProxy.Generators.ClassProxyGenerator.GenerateCode(Type[] interfaces, ProxyGenerationOptions options)
at Castle.DynamicProxy.DefaultProxyBuilder.CreateClassProxyType(Type classToProxy, Type[] additionalInterfacesToProxy, ProxyGenerationOptions options)
at Castle.DynamicProxy.ProxyGenerator.CreateClassProxyType(Type classToProxy, Type[] additionalInterfacesToProxy, ProxyGenerationOptions options)
at Castle.DynamicProxy.ProxyGenerator.CreateClassProxy(Type classToProxy, Type[] additionalInterfacesToProxy, ProxyGenerationOptions options, Object[] constructorArguments, IInterceptor[] interceptors)
at Moq.CastleProxyFactory.CreateProxy(Type mockType, IInterceptor interceptor, Type[] interfaces, Object[] arguments)
It seems like Moq is trying to mock the internal virtual method Pipeline in the BlobBaseClient, which the BlockBlobClient inherits from.
Seeing as the method is internal and in another assembly, I cannot override it. However if I define a property with the same name, ala:
public class TestBlockBlobClient : BlockBlobClient
{
public HttpPipeline Pipeline => null!;
}I get the same error, but with the next internal virtual property
System.TypeLoadException : Method 'get_Version' on type 'Castle.Proxies.TestBlockBlobClientProxy' from assembly 'DynamicProxyGenAssembly2, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' is overriding a method that is not visible from that assembly.
which is also a property on the superclass
So my theory is that there's something that's going on with the internal virtual properties, but only in a subclass of a subclass in another assembly.
Unfortunately, I cannot reproduce the problem, if I try to mimick the same thing locally (e.g. create two assemblies and the same internal virtual structure). I'm not sure if this is a Windsor or a Moq problem either.
