对 Mock.Setup 的后续调用会产生相同的对象实例

发布于 2025-01-08 11:42:50 字数 938 浏览 0 评论 0原文

我正在设置一个模拟,如下所示。它被传递到目标的构造函数中。目标有一个 Decrypt 方法,该方法在目标的生命周期内被调用两次。每次调用 Decrypt 方法时,它都会处理在安装程序中“更新”的证书。但是,当第二次调用 Decrypt 对象时,我在尝试解密时得到了一个 ObjectDispose 方法。如果我用调用 GetCertificate() 的 ICertificateHelperAdapter 的 Fake 实现替换此 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");
    }

I am setting up a Mock as shown below. It is passed into the constructor of the target. The target has a Decrypt method that is called twice within the lifetime of the target. Each time the Decrypt method is called, it Disposes of the certificate that is "newed" up in the Setup. However, when calling the Decrypt object the second time, I am getting an ObjectDisposed method upon attempting the decryption. If I replace this Mock with a Fake implementation of ICertificateHelperAdapter that calls GetCertificate(), then the second call to Decrypt works properly.

I am deducing that when I use the Mock, it is not returning me a new instance of the object on subsequent calls to GetCertificate. Is this by design?

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

我们只是彼此的过ke 2025-01-15 11:42:50

Returns 的不同重载表现不同:

您使用的 T Returns(T value) 始终返回相同的实例。

但有一个使用 Func 的惰性版本。它们看起来像T Returns(Funcvalue),并且在调用设置方法时每次都会评估参数函数。

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

它会调用您的 < code>GetCertificate() 两次。

The different overloads of Returns<T> behaves differently:

The one with T Returns<T>(T value) what you are using is always returning the same instance.

But there is a lazy version which uses Func<T>. They are looks like T Returns<T>(Func<T> value) and they will evaluate each time the parameter function when the setup method is called.

Sample from the Moq site:

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

Change your setup to:

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

And it will call your GetCertificate() twice.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文