最小化一个索引属性,并在返回/回调中使用索引值 [英] Moq an indexed property and use the index value in the return/callback

查看:106
本文介绍了最小化一个索引属性,并在返回/回调中使用索引值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想添加一个具有索引的属性,并且希望能够在回调中使用索引值,就像您可以在回调中为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和实例XI的情况下,将自动创建默认行为为XMock<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.

推荐答案

方法SetupSet采用普通委托,而不是类型为

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆