Последующие вызовы результата Mock.Setup в одном экземпляре объекта
Я настраиваю Mock, как показано ниже. Он передается в конструктор цели. Цель имеет метод Decrypt, который вызывается дважды в течение срока действия цели. Каждый раз, когда вызывается метод Decrypt, он выдает сертификат, "обновленный" в программе установки. Однако при вызове объекта Decrypt во второй раз я получаю метод ObjectDisposed при попытке дешифрования. Если я заменил этот Mock на Fake-реализацию 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
Различные перегрузки 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()
.