Closed
Description
(Cross-posting some details from nsubstitute/NSubstitute#378)
C# 7.2 introduced the possibility of using reference semantics for value types - this is done by applying the in
modifier for value-type parameters in method signatures.
Castle.Core does not seem to support generating mocks for interfaces that use in
modifiers for value types. This has been reproduced using Castle.Core indirectly through the latest stable versions of Moq and NSubstitute:
namespace SomeProject.Tests
{
public readonly struct Struct
{
}
public interface IStructByRefConsumer
{
void Consume(in Struct message);
}
public interface IStructByValueConsumer
{
void Consume(Struct message);
}
public class TempSpec
{
// Fails.
[Fact]
internal void Struct_ByRef_Moq_Test()
{
_ = Mock.Of<IStructByRefConsumer>();
}
// Fails.
[Fact]
internal void Struct_ByRef_NSubstitute_Test()
{
_ = Substitute.For<IStructByRefConsumer>();
}
// Passes.
[Fact]
internal void Struct_ByValue_Moq_Test()
{
_ = Mock.Of<IStructByValueConsumer>();
}
// Passes.
[Fact]
internal void Struct_ByValue_NSubstitute_Test()
{
_ = Substitute.For<IStructByValueConsumer>();
}
}
}
Posted below is the part of the stracktrace that's common between the failing Moq and NSubstitute tests:
Message: System.TypeLoadException : Signature of the body and declaration in a method implementation do not match. Type: 'Castle.Proxies.IStructByRefConsumerProxy'. Assembly: 'DynamicProxyGenAssembly2, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null'.
Result StackTrace:
at System.Reflection.Emit.TypeBuilder.TermCreateClass(RuntimeModule module, Int32 tk, ObjectHandleOnStack type)
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.InterfaceProxyWithoutTargetGenerator.GenerateType(String typeName, Type proxyTargetType, Type[] interfaces, INamingScope namingScope)
at Castle.DynamicProxy.Generators.InterfaceProxyWithTargetGenerator.<>c__DisplayClass6_0.<GenerateCode>b__0(String n, INamingScope s)
at Castle.DynamicProxy.Generators.BaseProxyGenerator.ObtainProxyType(CacheKey cacheKey, Func`3 factory)
at Castle.DynamicProxy.ProxyGenerator.CreateInterfaceProxyWithoutTarget(Type interfaceToProxy, Type[] additionalInterfacesToProxy, ProxyGenerationOptions options, IInterceptor[] interceptors)
Metadata
Metadata
Assignees
Labels
No labels