在我的图书馆里,我有一个简单的课程:
public class FormDataJsonBinderProvider : IModelBinderProvider
{
// code ommited
public IModelBinder GetBinder(ModelBinderProviderContext context)
{
// some logic
}
}我想测试它,但要做到这一点,我必须以某种方式模拟ModelMetadata(context.Metadata是ModelMetadata类型),这是一个具有该签名的abstract类:
public abstract class ModelMetadata : IEquatable<ModelMetadata?>, IModelMetadataProvider
{
// some props and methods
internal virtual bool PropertyHasValidators => false; // problematic property :(
}在我的测试中
[Test]
public void GetBinder_SimpleType_ShouldThrowException()
{
// Arrange
var metadata = Substitute.For<ModelMetadata>();
metadata.IsComplexType.Returns(false);
}我得到了System.ArgumentException : Can not instantiate proxy of class: Microsoft.AspNetCore.Mvc.ModelBinding.ModelMetadata. Could not find a parameterless constructor. (Parameter 'constructorArguments'),这是完全公平的。
所以。我做了一个TestModelMetadata类:
public abstract class TestModelMetadata : ModelMetadata {
public TestModelMetadata() : base(new ModelMetadataIdentity()) { }
public new virtual bool IsComplexType { get; }
public override IReadOnlyDictionary<object, object> AdditionalValues { get; }
// More overridden props
}我就是这样用的:
public void GetBinder_SimpleType_ShouldThrowException()
{
// Arrange
var metadata = Substitute.For<TestModelMetadata>();
metadata.IsComplexType.Returns(false);
}在这里我得到一个奇怪的例外:
System.TypeLoadException : Method 'get_PropertyHasValidators' on type 'Castle.Proxies.TestModelMetadataProxy' from assembly 'DynamicProxyGenAssembly2, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' is overriding a method that is not visible from that assembly.
at System.Reflection.Emit.TypeBuilder.CreateTypeNoLock()
at System.Reflection.Emit.TypeBuilder.CreateTypeInfo()
at Castle.DynamicProxy.Generators.Emitters.AbstractTypeEmitter.BuildType()
at Castle.DynamicProxy.Generators.BaseClassProxyGenerator.GenerateType(String name, INamingScope namingScope)
at Castle.DynamicProxy.Generators.BaseProxyGenerator.<>c__DisplayClass13_0.<GetProxyType>b__0(CacheKey cacheKey)
at Castle.Core.Internal.SynchronizedDictionary`2.GetOrAdd(TKey key, Func`2 valueFactory)
at Castle.DynamicProxy.Generators.BaseProxyGenerator.GetProxyType()
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 NSubstitute.Proxies.CastleDynamicProxy.CastleDynamicProxyFactory.CreateProxyUsingCastleProxyGenerator(Type typeToProxy, Type[] additionalInterfaces, Object[] constructorArguments, IInterceptor[] interceptors, ProxyGenerationOptions proxyGenerationOptions)
at NSubstitute.Proxies.CastleDynamicProxy.CastleDynamicProxyFactory.GenerateTypeProxy(ICallRouter callRouter, Type typeToProxy, Type[] additionalInterfaces, Object[] constructorArguments)
at NSubstitute.Proxies.CastleDynamicProxy.CastleDynamicProxyFactory.GenerateProxy(ICallRouter callRouter, Type typeToProxy, Type[] additionalInterfaces, Object[] constructorArguments)
at NSubstitute.Core.SubstituteFactory.Create(Type[] typesToProxy, Object[] constructorArguments, Boolean callBaseByDefault)
at NSubstitute.Core.SubstituteFactory.Create(Type[] typesToProxy, Object[] constructorArguments)
at NSubstitute.Substitute.For(Type[] typesToProxy, Object[] constructorArguments)
at NSubstitute.Substitute.For[T](Object[] constructorArguments)所以问题是:
如何模拟ModelMetadata类以在测试中使用?
发布于 2022-07-18 07:53:17
与其仅为测试创建一个TestModelMetadata类,不如告诉NSubstitute在ModelMetadata上使用一个现有的构造函数,如下所示:
[Test]
public void GetBinder_SimpleType_ShouldThrowException()
{
// Arrange
var metadata = Substitute.For<ModelMetadata>(new ModelMetadataIdentity());
metadata.IsComplexType.Returns(false);
}https://stackoverflow.com/questions/73005436
复制相似问题