使用 NSubstitute 的自定义属性

Custom Attributes with NSubstitute

我目前正在用 NSubstitute 模拟一个 Interface,它基本上是一个 class 的表示,具有两个属性和一个方法。

LoginViewModel = Substitute.For<ILoginViewModel>();

模拟接口被实例化,然后传递到一个方法中,该方法反映它以获取所有自定义属性。

LoginViewModel.Username = "User1";
LoginViewModel.Password = "Password1";

接口具体实现上的每个属性都有一个自定义属性,但是在反映时,编译器不显示任何自定义属性。

[CustomRequired]
public string Username { get; set; }

[CustomRequired]
public string Password { get; set; }

没有 NSubstitute 的情况下测试这个作品。我的问题是:NSubstitute 是否去除了自定义属性?还是有办法让他们通过?

我不太了解自定义属性,所以值得 double checking the information 在我的回答中。

首先,NSubstitute 会去掉 some specific attributes,但一般不会去掉属性。 (另外:NSubstitute 使用 Castle DynamicProxy 来生成代理类型,所以为了更准确,NSubstitute 要求 Castle DP 去除这些。:))

其次,如果在接口上声明属性,它们将 not flow on to the class. They will however be available via the interface type itself. They will also be available if declared on a class and on substitutes for that class (provided the attribute is not configured explicitly to prevent being inherited):

public class MyAttribute : Attribute { }
public interface IHaveAttributes {
    [My] string Sample { get; set; }
}
public class HaveAttributes : IHaveAttributes {
    [My] public virtual string Sample { get; set; }
}
public class NoAttributes : IHaveAttributes {
    public virtual string Sample { get; set; }
}

[Test]
public void TestAttributes()
{
    // WORKS for class:
    var sub = Substitute.For<HaveAttributes>();
    var sampleProp = sub.GetType().GetProperty("Sample");
    var attributes = Attribute.GetCustomAttributes(sampleProp, typeof(MyAttribute));
    Assert.AreEqual(1, attributes.Length);

    // WORKS directly from interface:
    var sampleInterfaceProp = typeof(IHaveAttributes).GetProperty("Sample");
    var attributes2 = Attribute.GetCustomAttributes(sampleInterfaceProp, typeof(MyAttribute));
    Assert.AreEqual(1, attributes2.Length);

    // Does NOT go from interface through to class (even non-substitutes):
    var no = new NoAttributes();
    var sampleProp2 = no.GetType().GetProperty("Sample");
    var noAttributes = Attribute.GetCustomAttributes(sampleProp2, typeof(MyAttribute));
    Assert.IsEmpty(noAttributes);
}