最小化一个索引属性,并在返回/回调中使用索引值 [英] Moq an indexed property and use the index value in the return/callback
问题描述
我想添加一个具有索引的属性,并且希望能够在回调中使用索引值,就像您可以在回调中为moq方法使用方法参数一样.可能最容易通过示例进行演示:
I want to moq a property that has an index, and I want to be able to use the index values in the callback, the same way you can use method arguments in the callback for moq'd methods. Probably easiest to demonstrate with an example:
public interface IToMoq
{
int Add(int x, int y);
int this[int x] { get; set; }
}
Action<int, int> DoSet = (int x, int y) =>
{
Console.WriteLine("setting this[{0}] = {1}", x, y);
throw new Exception("Do I ever get called?");
};
var mock = new Mock<IToMoq>(MockBehavior.Strict);
//This works perfectly
mock.Setup(m => m.Add(It.IsAny<int>(), It.IsAny<int>()))
.Returns<int, int>((a, b) => a + b);
//This compiles, but my callback never seems to be called
mock.SetupSet(m => m[It.IsAny<int>()] = It.IsAny<int>())
.Callback(DoSet);
var obj = mock.Object;
Console.WriteLine("Add(3,4) => {0}", obj.Add(3, 4)); //Works perfectly
obj[1] = 2; //Does not throw, why?
为明确起见,我希望get
的回调/返回方法为Func<int,int>
,而set
的回调/返回方法为Action<int,int>
.尝试Mike的建议,您可以为set
做到这一点,但有一个主要限制:
To clarify, I want the callback/returns method for the get
to be Func<int,int>
, and the callback/returns method for the set
to be Action<int,int>
. Trying what Mike suggested, you can sort of do this for set
, but with one major limitation:
mock.SetupSet(m => m[23] = It.IsAny<int>())
.Callback(DoSet).Verifiable();
然后确实使用值(23,<any>)
调用了回调DoSet
.不幸的是,使用It.IsAny<int>()
代替23
似乎表现为0
,而不是<any>
.
The callback DoSet
is indeed then called with values (23,<any>)
. Unfortunately, using It.IsAny<int>()
instead of 23
seems to behave as 0
, rather than <any>
.
此外,我找不到用Returns
调用SetupGet
的方法,其中Returns
接受甚至可以编译的Func<int,int>
.
Also, I couldn't find a way of calling SetupGet
with Returns
where Returns
takes a Func<int,int>
that would even compile.
是否可以使用Moq?
Is it possible to use Moq for this?
动机:我只是在玩Moq,试图用它来提供流畅的API来执行拦截.也就是说,在给定接口I
和实例X
为I
的情况下,将自动创建默认行为为X
的Mock<I>
代理.
Motivation: I'm just playing with Moq, attempting to use it to provide a fluent API for performing interception. That is, given an interface I
and an instance X
of I
, automatically create a Mock<I>
proxy with behaviour defaulting to X
.
直接使用Castle DP可能更有意义,但是我喜欢Moq Expression Tree语法.
Would probably make more sense to work directly with Castle DP, but I like the Moq Expression Tree syntax.
推荐答案
The method SetupSet
takes a plain delegate, not an expression tree of type Expression<...>
like many other Moq methods.
因此,Moq无法看到您使用的是It.IsAny
.取而代之的是,It.IsAny
被称为 (不是我们想要的),Moq仅看到其返回值,恰好是default(int)
或0
.
For that reason Moq cannot see that you used It.IsAny
. Instead, It.IsAny
is called (not what we want) and Moq sees its return value only which happens to be default(int)
, or 0
.
这篇关于最小化一个索引属性,并在返回/回调中使用索引值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!