3

我有什么可能的解决方法来使用 Moq 模拟这个对象。返回的错误消息是:“非虚拟(在 VB 中可覆盖)成员上的设置无效:p => p.Certificate.SubjectName.Name”

        var st = new Mock<X509SecurityToken>();
        st.SetupGet(p => p.Certificate.SubjectName.Name).Returns("test1");
        var target = new X509IssuerNameRegistry("test1", "test2");

        var actual = target.GetIssuerName(st.Object);

        Assert.AreEqual<string>("test1", actual, "Actual security token did not equal expected security token");

注意:我正在尝试模拟X509SecurityToken。这是正在测试的类:

公共类 X509IssuerNameRegistry : IssuerNameRegistry { 只读列表 _trustedSubjectNames = new List();

public X509IssuerNameRegistry(params string[] trustedSubjectNames)
{
    _trustedSubjectNames = new List<string>(trustedSubjectNames);
}

public override string GetIssuerName(SecurityToken securityToken)
{
    var x509Token = securityToken as X509SecurityToken;
    if (x509Token != null)
    {
        if (_trustedSubjectNames.Contains(x509Token.Certificate.SubjectName.Name))
        {
            return x509Token.Certificate.SubjectName.Name;
        }
    }
    throw new SecurityTokenException("Untrusted issuer.");
}

}

任何工作轮次(使用起订量)还是我应该寻找另一个模拟框架来完成这个?

4

2 回答 2

2

不,Moq(就像任何继承类一样)不能覆盖非虚拟方法,因此除非您可以使 Name 成为虚拟属性(通过更改或包装类),否则 Moq 不能模拟它。

如果可能的话,我建议您将您的属性更改为虚拟的,因为这将允许您使用任何模拟框架。据我所知,只有 3 个可以模拟非虚拟方法,它们都不是免费的;

于 2012-09-17T04:35:16.987 回答
0

您可以寻找一些允许您“破解”无法简单模拟的代码的框架(即不包含虚拟方法/不是接口),但这可能是矫枉过正(并且某些选项不是免费的,例如TypeMock Isolator for例子)。

一种更简单的方法可能是 abstract X509SecurityToken,例如:

interface ISecurityToken
{
    string SubjectName { get; }
    // ...
}

然后,实现一个包装器,它也实现了上面指定的接口:

class SecurityToken : ISecurityToken
{
    X509SecurityToken token;
    public SecurityToken(X509SecurityToken token)
    {
        this.token = token;
    }
    public string SubjectName { get { return token.SubjectName.Name; } }
}

然后,在整个代码中,您应该使用ISecurityTokeninterface 而不是X509SecurityToken,这将是相当简单的模拟。

于 2012-09-17T04:34:36.333 回答