Могу ли я использовать Moq в этой ситуации?

Какой возможный обходной путь у меня есть для насмешки этого объекта с помощью 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");

Примечание: я пытаюсь Mock X509SecurityToken. Вот тестируемый класс:

открытый класс X509IssuerNameRegistry: IssuerNameRegistry {только для чтения List _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.");
}

}

Какие-либо обходные пути для этого (с использованием Moq) или я должен искать другие насмешливые рамки для достижения этой цели?

2 ответа

Нет, Moq (как и любой наследующий класс) не может переопределять не виртуальные методы, поэтому, если вы не можете сделать Name виртуальным свойством (путем изменения или обертывания класса), Moq не может его смоделировать.

Я бы посоветовал вам по возможности изменить вашу собственность на виртуальную, поскольку это позволит вам использовать любую фальшивую среду. Насколько я знаю, есть только 3, которые могут издеваться над не виртуальными методами, ни один из них не является бесплатным;

Вы могли бы искать какую-то инфраструктуру, которая позволяет вам "взломать" код, который не может быть просто смоделирован (то есть не содержит виртуальных методов / не является интерфейсом), но это может быть излишним (и некоторые опции не являются бесплатными, как TypeMock Isolator пример).

Более простым подходом может быть абстракция 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; } }
}

Затем, во всем вашем коде, вы должны использовать ISecurityToken интерфейс вместо X509SecurityToken, что было бы довольно просто издеваться.

Другие вопросы по тегам