使用Moq的Raise触发事件时遭遇TargetParameterCountException求助
解决Moq触发异步事件时的参数不匹配异常
问题场景
我定义了一个带异步事件的类:
event Func<ApplicationMessageProcessedEventArgs, Task> ApplicationMessageProcessedAsync;
用Moq测试该事件处理逻辑时,写了这段代码:
mqttClient.Mock.Raise(client => client.ApplicationMessageReceivedAsync += null, eventArg);
结果抛出参数不匹配的异常,堆栈信息如下:
System.Reflection.TargetParameterCountException: Parameter count mismatch. at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture) at System.Delegate.DynamicInvokeImpl(Object[] args) at System.Delegate.DynamicInvoke(Object[] args) at Moq.Extensions.InvokePreserveStack(Delegate del, IReadOnlyList`1 args) in C:\projects\moq4\src\Moq\Extensions.cs:line 158 at Moq.Mock.RaiseEvent(Mock mock, LambdaExpression expression, Stack`1 parts, Object[] arguments) in C:\projects\moq4\src\Moq\Mock.cs:line 745 at Moq.Mock.RaiseEvent[T](Mock mock, Action`1 action, Object[] arguments) in C:\projects\moq4\src\Moq\Mock.cs:line 695 at Moq.Mock`1.Raise(Action`1 eventExpression, EventArgs args) in C:\projects\moq4\src\Moq\Mock`1.cs:line 1366 at MqttChannel.MqttChannelTest.MqttChannel_ProcessNewMessage() in C:\Development\Shared\OT.Test\MqttChannel\MqttChannelTest.cs:line 298 at Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.ThreadOperations.ExecuteWithAbortSafety(Action action)
问题根源
Moq的Raise方法是为标准事件委托设计的,比如EventHandler<T>,这类委托的签名是void (object sender, TEventArgs e),需要两个参数。而你用的是异步委托Func<ApplicationMessageProcessedEventArgs, Task>,它只接受一个事件参数,两者参数数量不匹配,所以触发异常。
解决办法
放弃用Moq的Raise,手动触发异步事件:
异步测试方法中使用
var eventHandler = mqttClient.Mock.Object.ApplicationMessageReceivedAsync; if (eventHandler != null) { await eventHandler(eventArg); }
同步测试方法中使用
var eventHandler = mqttClient.Mock.Object.ApplicationMessageReceivedAsync; eventHandler?.Invoke(eventArg).Wait();
注意:检查事件名称是否一致——你定义的事件是ApplicationMessageProcessedAsync,但测试代码里写的是ApplicationMessageReceivedAsync,如果是笔误请修正。
内容的提问来源于stack exchange,提问作者Pavel Reichl
相关产品推荐
相关产品推荐

