C# 具有5+;参数和访问调用参数
我有一个函数,我想要Moq。问题是它需要5个参数。该框架仅包含C# 具有5+;参数和访问调用参数,c#,moq,delegates,action,C#,Moq,Delegates,Action,我有一个函数,我想要Moq。问题是它需要5个参数。该框架仅包含Action和Moq的genericCallBack()仅重载Action和四个generic版本。有没有一个优雅的解决办法 这就是我想做的: public class Filter : IFilter { public int Filter(int i1, int i2, int i3, int i4, int i5){return 0;} } //Moq code: var mocker = new Mock
Action
和Moq的genericCallBack()
仅重载Action和四个generic版本。有没有一个优雅的解决办法
这就是我想做的:
public class Filter : IFilter
{
public int Filter(int i1, int i2, int i3, int i4, int i5){return 0;}
}
//Moq code:
var mocker = new Mock<IFilter>();
mocker.Setup(x => x.Filter(
It.IsAny<int>(),
It.IsAny<int>(),
It.IsAny<int>(),
It.IsAny<int>(),
It.IsAny<int>(),
It.IsAny<int>())
.Callback
(
(int i1, int i2, int i3, int i4, int i5) => i1 * 2
);
公共类筛选器:IFilter
{
公共int筛选器(inti1、inti2、inti3、inti4、inti5){返回0;}
}
//最小起订量代码:
var mocker=new Mock();
mocker.Setup(x=>x.Filter(
It.IsAny(),
It.IsAny(),
It.IsAny(),
It.IsAny(),
It.IsAny(),
It.IsAny())
.回拨
(
(inti1,inti2,inti3,inti4,inti5)=>i1*2
);
Moq不允许这样做,因为没有需要5个以上参数的通用操作。我已经求助于制作自己的存根。显然,最好使用Moq进行所有验证,等等。我知道这可能会破坏您的设计,但是有这么多参数,传递参数数组不是更好吗?这实际上是q简单。只要定义你自己的
动作
,你就可以开始了
public delegate void Action<T1, T2, T3, T4, T5>(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5);
公共代表无效行动(T1、T2、T3、T4、T5);
这就是框架中定义的所有
操作
,操作
,…,操作
。仅此而已。简单!如果不想修改源代码,请使用扩展方法扩展moq框架
//Extension Method
public static class MoqExtensions
{
public static void Callback<T1, T2, T3, T4, T5>(this ICallback iCallBack, Action<T1, T2, T3, T4, T5> action)
{
}
}
//Your class and interface
public interface IMyClass
{
void Method(string arg1, string arg2, string arg3, string arg4, string arg5);
}
public class MyClass : IMyClass
{
public void Method(string arg1, string arg2, string arg3, string arg4, string arg5)
{
//Do something
}
}
//Your test
[TestMethod]
public void ExampleTest()
{
Mock<IMyClass> mockMyClass = new Mock<IMyClass>();
mockMyClass.Setup(s => s.Method(It.IsAny<string>(),
It.IsAny<string>(),
It.IsAny<string>(),
It.IsAny<string>(),
It.IsAny<string>()))
.Callback<string, string, string, string, string>((string arg1, string arg2, string arg3, string arg4, string arg5)
=> { /* Run your mock here */ });
}
//扩展方法
公共静态类MoqExtensions
{
公共静态无效回调(此ICallback ICallback,操作)
{
}
}
//您的类和接口
公共接口IMyClass
{
void方法(字符串arg1、字符串arg2、字符串arg3、字符串arg4、字符串arg5);
}
公共类MyClass:IMyClass
{
公共void方法(字符串arg1、字符串arg2、字符串arg3、字符串arg4、字符串arg5)
{
//做点什么
}
}
//你的测试
[测试方法]
public void ExampleTest()
{
Mock mockMyClass=new Mock();
mockMyClass.Setup(s=>s.Method(It.IsAny()),
It.IsAny(),
It.IsAny(),
It.IsAny(),
It.IsAny())
.Callback((字符串arg1、字符串arg2、字符串arg3、字符串arg4、字符串arg5)
=>{/*在此处运行模拟*/});
}
这在Moq 4.0(4.0.10827)的最终版本中得到了支持,该版本于2011年4月12日发布。如果您使用.NET 4,您将能够模拟16个参数。我知道这是一篇旧文章,但我认为此代码可能会帮助其他有此问题的人使用旧版本的Moq。下面是一个有5个和6个参数的示例,它可以扩展以支持任意数量的参数
我已经用版本3.1.0.0测试过了,但是它应该也可以用在其他版本上
秘密是使用反射访问基础类上的受保护方法“SetCallbackWithArguments”
希望这对某人有用
public delegate void Action<T1, T2, T3, T4, T5>(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5);
public delegate void Action<T1, T2, T3, T4, T5, T6>(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6);
public static class MoqExtensions
{
public static ICallbackResult Callback<T1, T2, T3, T4, T5>(this ICallback call, Action<T1, T2, T3, T4, T5> callback)
{
call.SetCallbackWithArguments(callback);
return (ICallbackResult)call;
}
public static ICallbackResult Callback<T1, T2, T3, T4, T5, T6>(this ICallback call, Action<T1, T2, T3, T4, T5, T6> callback)
{
call.SetCallbackWithArguments(callback);
return (ICallbackResult)call;
}
public static void SetCallbackWithArguments(this ICallback call, Delegate callback)
{
MethodInfo methodInfo = call.GetType().GetMethod("SetCallbackWithArguments", BindingFlags.NonPublic | BindingFlags.Instance);
methodInfo.Invoke(call, new object[] { callback });
}
}
公共代理无效操作(T1 arg1、T2 arg2、T3 arg3、T4 arg4、T5 arg5);
公开代表无效行动(T1 arg1、T2 arg2、T3 arg3、T4 arg4、T5 arg5、T6 arg6);
公共静态类MoqExtensions
{
公共静态ICallbackResult回调(此ICallback调用、操作回调)
{
SetCallbackWithArguments(回调);
return(ICallbackResult)调用;
}
公共静态ICallbackResult回调(此ICallback调用、操作回调)
{
SetCallbackWithArguments(回调);
return(ICallbackResult)调用;
}
公共静态void SetCallbackWithArguments(此ICallback调用、委托回调)
{
MethodInfo MethodInfo=call.GetType().GetMethod(“SetCallbackWithArguments”,BindingFlags.NonPublic | BindingFlags.Instance);
调用(调用,新对象[]{callback});
}
}
可能不会对您有所帮助,但在.NET 4.0中,Action最多可以使用16个参数!即使您在.NET 4.0中,Moq在其最新的beta版中仍然最多只支持4个参数。要解决此问题,您必须下载源代码并自行下载。您可以使用扩展方法,您仍然需要修改Moq源代码以支持在回调中输入四个以上的参数。@“Robert Harvey”-是的,你是对的。我忽略了这一点。也许咖喱可以发挥作用?我看到的唯一解决方案是更改Moq重载以执行5个以上参数的操作。你说的“咖喱”是什么意思?+1,虽然参数对象可能更好,如果参数代表您在下一个响应中提到的不同概念,我需要更改Moq本身,因为它不允许此重载。无论如何,我需要泛型,以便访问调用参数。实际上,正如Mark指出的,更好的解决方案是传递一个objec不包含您需要的所有参数。当然,这将改变您模拟它的方式。然后呢?我仍然需要编写自己的方法,这并不比修改源代码简单。我更新了我的代码示例以提供一个简单的示例。您所做的只是扩展ICallback接口,它是moq框架的一部分。您是fa吗熟悉创建扩展方法吗?你的扩展方法实际上什么都不做,那么除了不让编译器抱怨之外,它如何工作呢?它工作得很好。不要因为你不能让它工作而放弃投票。你能给出一个你所做的示例吗。请参阅Paul Wardle的答案,它实际上完成了这是一个问题尝试。