在 Moq 中分配 out/ref 参数
是否可以使用 Moq (3.0+) 分配 out
/ref
参数?
我研究过使用 Callback()
,但 Action<>
不支持 ref 参数,因为它基于泛型。 我还希望在 ref
参数的输入上放置一个约束 (It.Is
),尽管我可以在回调中执行此操作。
我知道 Rhino Mocks 支持此功能,但我正在从事的项目已经在使用 Moq。
Is it possible to assign an out
/ref
parameter using Moq (3.0+)?
I've looked at using Callback()
, but Action<>
does not support ref parameters because it's based on generics. I'd also preferably like to put a constraint (It.Is
) on the input of the ref
parameter, though I can do that in the callback.
I know that Rhino Mocks supports this functionality, but the project I'm working on is already using Moq.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(15)
对于“out”,以下内容似乎对我有用。
我猜当您调用安装程序时,Moq 会查看“expectedValue”的值并记住它。
对于
ref
,我也在寻找答案。我发现以下快速入门指南很有用:
https://github.com/Moq/moq4/wiki/Quickstart
For 'out', the following seems to work for me.
I'm guessing that Moq looks at the value of 'expectedValue' when you call Setup and remembers it.
For
ref
, I'm looking for an answer also.I found the following QuickStart guide useful:
https://github.com/Moq/moq4/wiki/Quickstart
Moq 版本 4.8 及更高版本大大改进了对 by-ref 参数的支持:
相同的模式适用于
out
参数。It.Ref.IsAny
也适用于 C# 7in
参数(因为它们也是 by-ref)。Moq version 4.8 and later has much improved support for by-ref parameters:
The same pattern works for
out
parameters.It.Ref<T>.IsAny
also works for C# 7in
parameters (since they are also by-ref).编辑:在 Moq 4.10 中,您现在可以将具有 out 或 ref 参数的委托直接传递给回调函数:
您必须定义委托并实例化它:
对于之前的 Moq 版本4.10:
Avner Kashtan 在他的博客中提供了一个扩展方法,允许从回调中设置 out 参数: Moq、回调和输出参数:一个特别棘手的边缘情况
该解决方案既优雅又哈克。 优雅之处在于它提供了流畅的语法,与其他 Moq 回调感觉很熟悉。 而且很hacky,因为它依赖于通过反射调用一些内部Moq API。
上面链接提供的扩展方法没有为我编译,所以我在下面提供了一个编辑版本。 您需要为您拥有的每个输入参数创建一个签名; 我已经提供了 0 和 1,但进一步扩展它应该很简单:
使用上述扩展方法,您可以测试不带参数的接口,例如:
.. 使用以下 Moq 设置:
编辑:要支持 void-return 方法,您只需添加新的重载方法:
这允许测试接口,例如:
EDIT: In Moq 4.10, you can now pass a delegate that has an out or ref parameter directly to the Callback function:
You will have to define a delegate and instantiate it:
For Moq version before 4.10:
Avner Kashtan provides an extension method in his blog which allows setting the out parameter from a callback: Moq, Callbacks and Out parameters: a particularly tricky edge case
The solution is both elegant and hacky. Elegant in that it provides a fluent syntax that feels at-home with other Moq callbacks. And hacky because it relies on calling some internal Moq APIs via reflection.
The extension method provided at the above link didn't compile for me, so I've provided an edited version below. You'll need to create a signature for each number of input parameters you have; I've provided 0 and 1, but extending it further should be simple:
With the above extension method, you can test an interface with out parameters such as:
.. with the following Moq setup:
Edit: To support void-return methods, you simply need to add new overload methods:
This allows testing interfaces such as:
这是来自 Moq 网站的文档:
This is documentation from Moq site:
在 Billy Jakes awnser 的基础上,我制作了一个带有 out 参数的完全动态模拟方法。 我将其发布在这里,供任何认为它有用的人使用。
Building on Billy Jakes awnser, I made a fully dynamic mock method with an out parameter. I'm posting this here for anyone who finds it usefull.
在 VS2022 中你可以简单地执行以下操作:
In VS2022 you can simply do:
似乎不可能开箱即用。 看起来有人尝试了解决方案
请参阅此论坛帖子
http://code.google.com/p/moq/issues/详细?id=176
这个问题
使用最小起订量验证参考参数的值
Seems like it is not possible out of the box. Looks like someone attempted a solution
See this forum post
http://code.google.com/p/moq/issues/detail?id=176
this question
Verify value of reference parameter with Moq
我确信 Scott 的解决方案在某一点上是有效的,
但这是不使用反射来查看私有 api 的一个很好的论据。 现在已经坏了。
我能够使用委托设置参数
I'm sure Scott's solution worked at one point,
But it's a good argument for not using reflection to peek at private apis. It's broken now.
I was able to set out parameters using a delegate
要返回一个值并设置 ref 参数,这里有一段代码:
然后声明与要模拟的方法的签名匹配的您自己的委托并提供您自己的方法实现。
To return a value along with setting ref parameter, here is a piece of code:
Then declare your own delegate matching the signature of to-be-mocked method and provide your own method implementation.
今天下午我为此苦苦挣扎了一个小时,但在任何地方都找不到答案。 在我自己尝试之后,我找到了一个对我有用的解决方案。
这里的关键是
mock.SetupAllProperties();
它将为您存根所有属性。 这可能不适用于每个测试用例场景,但如果您关心的只是获取YourMethod
的返回值
,那么这将工作得很好。I struggled with this for an hour this afternoon and could not find an answer anywhere. After playing around on my own with it I was able to come up with a solution which worked for me.
The key here is
mock.SetupAllProperties();
which will stub out all of the properties for you. This may not work in every test case scenario, but if all you care about is getting thereturn value
ofYourMethod
then this will work fine.在我简单地创建一个新的“假”类的实例(该类实现您尝试模拟的任何接口)之前,我对这里的许多建议进行了挣扎。 然后您可以简单地使用方法本身设置 out 参数的值。
I struggled with many of the suggestions here before I simple created an instance of a new 'Fake' class that implements whatever interface you are trying to Mock out. Then you can simply set the value of the out parameter with the method itself.
以下是一个正在运行的示例。
请注意,设置中没有退货,因为没有退货。
The following is an example that is working.
Note there is no Returs in the setup as there is no returns.
这可以是一个解决方案。
This can be a solution .
类似的东西就可以做到这一点:
要模拟的方法将是
然后模拟部分将是:
Something like that does the trick:
method to be mocked would be
Then the mock part would be:
对于任何希望使用
It.IsAny
作为输出参数的人,对 Craig Celeste 的答案进行了增强:如果满足以下条件,您还可以使用
Returns
而不是Callback
你的方法还需要返回一些东西。An enhancement on Craig Celeste's answer for any who wish to use
It.IsAny
for the out parameter:You could also use
Returns
instead ofCallback
if your method also needs to return something.