Последующие вызовы Mock.Setup приводят к тому же экземпляру объекта - PullRequest
14 голосов
/ 24 февраля 2012

Я настраиваю макет, как показано ниже.Он передается в конструктор цели.У цели есть метод Decrypt, который вызывается дважды в течение времени жизни цели.Каждый раз, когда вызывается метод Decrypt, он удаляет сертификат, «обновленный» в программе установки.Однако при повторном вызове объекта Decrypt я получаю метод ObjectDisposed при попытке расшифровки.Если я заменим этот Mock на фальшивую реализацию ICertificateHelperAdapter, которая вызывает GetCertificate (), то второй вызов Decrypt будет работать правильно.

Я делаю вывод, что когда я использую Mock, он не возвращает мне новый экземпляр объекта при последующих вызовах GetCertificate.Это по замыслу?

    private Mock<ICertificateHelperAdapter> GetCertificateHelperAdapter()
    {
        Mock<ICertificateHelperAdapter> certificateHelper = new Mock<ICertificateHelperAdapter>();

        certificateHelper.Setup(
            ch => ch.GetCertificate(CertStoreName.My, StoreLocation.LocalMachine, It.IsAny<string>())).Returns(this.GetCertificate()).Verifiable();
        return certificateHelper;
    }

    private X509Certificate2 GetCertificate()
    {
        return new X509Certificate2(Environment.CurrentDirectory + "\\" + "azureconfig.pfx", "dingos");
    }

1 Ответ

19 голосов
/ 24 февраля 2012

Различные перегрузки Returns<T> ведут себя по-разному:

Тот с T Returns<T>(T value), который вы используете, всегда возвращает один и тот же экземпляр.

Но есть ленивая версия, которая использует Func<T>. Они выглядят как T Returns<T>(Func<T> value) и будут оценивать каждый раз функцию параметра при вызове метода настройки.

Образец с сайта Moq :

// lazy evaluating return value
mock.Setup(foo => foo.GetCount()).Returns(() => count);

Измените настройки на:

certificateHelper.Setup(ch => 
   ch.GetCertificate(CertStoreName.My, StoreLocation.LocalMachine, It.IsAny<string>()))
.Returns(() => this.GetCertificate()).Verifiable(); //note the lambda in Returns

И он позвонит вашему GetCertificate() дважды.

...