更新:我刚刚意识到您实际上可以使用TypeDescriptor.AddAttributes将属性添加到现有类型,这可以针对实例或 aa 类型执行:
Mock<IRepository> repositoryMock = new Mock<IRepository>();
CustomAttribute attribute = new CustomAttribute();
// option #1: to the instance
TypeDescriptor.AddAttributes(repositoryMock.Object, attribute );
// option #2: to the generated type
TypeDescriptor.AddAttributes(repositoryMock.Object.GetType(), attributes);
如果需要,AddAttribute 会返回一个 TypeDescriptorProvider,可以将其传递给TypeDescriptor.RemoveProvider以在之后删除属性。
请注意,Attribute.GetCustomAttributes不会找到在运行时以这种方式添加的属性。相反,请使用TypeDescriptor.GetAttributes。
原始答案
我不相信 Moq(或任何其他模拟框架)支持自定义属性。我知道 Castle Proxy(通常用于实际创建类的框架)确实支持它,但无法通过 Moq 访问它。
最好的办法是将加载属性的方法抽象到接口(接受类型和属性类型)中,然后模拟它。
编辑:例如:
public interface IAttributeStrategy
{
Attribute[] GetAttributes(Type owner, Type attributeType, bool inherit);
Attribute[] GetAttributes(Type owner, bool inherit);
}
public class DefaultAttributeStrategy : IAttributeStrategy
{
public Attribute[] GetAttributes(Type owner, Type attributeType, bool inherit)
{
return owner.GetCustomAttributes(attributeType, inherit);
}
public Attribute[] GetAttributes(Type owner, bool inherit)
{
return owner.GetCustomAttributes(inherit);
}
}
需要属性的类使用 IAttributeStrategy 的实例(通过 IoC 容器,或者将其可选地传递给构造函数)。通常它将是一个 DefaultAttributeStrategy,但您现在可以模拟 IAttributeStrategy 以覆盖输出。
这听起来可能令人费解,但添加抽象层比尝试实际模拟属性要容易得多。