You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Moq模拟IPeakCommunication,以Send参数触发RequestReceived事件

问题描述

我有一个IPeakCommunication接口及其派生类PeakCommunication,派生类中的Send(RequestData request)方法执行时,会触发RequestReceived事件并传入request作为参数。现在需要为与IPeakCommunication交互的类编写单元测试,要创建Mock对象,使得调用Send方法时,能将传入的RequestData参数作为事件参数触发RequestReceived事件,但不知道怎么实现。

接口定义如下:

public interface IPeakCommunication : IDisposable
{
#region Delegates
delegate void PeakRequestReceivedHandler(RequestData data);
#endregion

#region Events
event PeakRequestReceivedHandler? RequestReceived;
#endregion

#region Methods
void Send(RequestData data);
#endregion
}

我尝试的代码:

var mockCommunication = new Mock<IPeakCommunication>();
mockCommunication.Setup(x => x.Send(It.IsAny<RequestData>()))
    .Raises(x => x.RequestReceived += null, new object[] { /*argument from Send()?*/ } );
解决方案

可以通过Moq的两种方式实现这个需求:

方法一:使用Raises的参数捕获重载

直接利用Raises的重载,它可以接收方法的参数并传递给事件:

var mockCommunication = new Mock<IPeakCommunication>();
mockCommunication.Setup(x => x.Send(It.IsAny<RequestData>()))
    // 这里的第二个参数data就是Send方法传入的RequestData
    .Raises((IPeakCommunication _, RequestData data) => _.RequestReceived += null, data);

方法二:结合Callback手动触发事件

先通过Callback捕获Send方法传入的参数,再手动触发事件:

var mockCommunication = new Mock<IPeakCommunication>();
mockCommunication.Setup(x => x.Send(It.IsAny<RequestData>()))
    .Callback<RequestData>(requestData => 
        // 触发RequestReceived事件并传入捕获到的参数
        mockCommunication.Raise(comm => comm.RequestReceived += null, requestData));

两种方式都能实现调用Send时,将传入的RequestData作为事件参数触发RequestReceived事件,可根据习惯选择。

内容的提问来源于stack exchange,提问作者Snail

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 23:47:37