对Mock.Setup的后续调用会导致同一个对象实例

Pet*_*oun 15 moq moq-3

我正在设置一个Mock,如下所示.它被传递到目标的构造函数中.目标具有Decrypt方法,该方法在目标的生命周期内被调用两次.每次调用Decrypt方法时,都会在安装程序中处置"新建"的证书.但是,当第二次调用Decrypt对象时,我在尝试解密时获得了ObjectDisposed方法.如果我用调用GetCertificate()的ICertificateHelperAdapter的伪实现替换这个Mock,那么第二次调用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");
    }
Run Code Online (Sandbox Code Playgroud)

nem*_*esv 20

不同的重载Returns<T>行为有所不同:

在一个与 T Returns<T>(T value)你正在使用总是返回同一个实例是什么.

但是有一个懒惰的版本使用Func<T>.它们看起来像,T Returns<T>(Func<T> value)并且每次调用setup方法时它们都会评估参数的功能.

来自Moq网站的样本:

// lazy evaluating return value
mock.Setup(foo => foo.GetCount()).Returns(() => count);
Run Code Online (Sandbox Code Playgroud)

将您的设置更改为:

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

它会打电话给你GetCertificate()两次.