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

时间:2012-02-24 04:33:32

标签: 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");
    }

1 个答案:

答案 0 :(得分:18)

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

使用T Returns<T>(T value)的人总是返回相同的实例。

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

来自Moq site的示例:

// 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()