我有下面的类负责根据某些业务条件引发事件。
public class EventRaiserClass : IEventRaiserClass
{
public event EventHandler SendEventToClient;
public void RaiseEventForClient()
{
SendEventToClient?.Invoke(this, EventArgs.Empty);
}
}
这是我的客户端类
public class Client :IClient
{
EventRaiserClass _eventRaiser;
public Client(EventRaiserClass eventraiser)
{
_eventRaise = eventraise;
_iotGwStatus.SendEventToClient += OnSendEventToClient;
}
private async void OnSendEventToClient(object sender, EventArgs e)
{
await SendEventToClient();
}
public async Task SendEventToClient()
{
//do some operation
}
}
EventRaiserClass
被注入(inject)到下面负责处理一些订单的类
public class ProcessRequest: IProcessRequest
{
IEventRaiserClass _evntRaiser;
public ProcessRequest(IEventRaiserClass evntRaiser)
{
_evntRaiser = evntRaiser;
}
public void Process(JObject json)
{
_evntRaiser.RaiseEventForClient();
}
}
现在,如何对 Process
方法进行单元测试?如何确保在调用 process
方法时引发事件?
最佳答案
据我所知,Client
类与这个问题无关?您只想测试调用 ProcessRequest.Process
调用 EventRaiserClass.RaiseEventForClient
。
一个简单的方法,没有任何模拟,使用 EventRaiserClass
:
var eventRaiser = new EventRaiserClass();
bool eventRaised = false;
eventRaiser.SendEventToClient += (o, e) => eventRaised = true;
var processRequest = new ProcessRequest(eventRaiser);
processRequest.Process(someJObject);
Assert.True(eventRaised);
您可以更进一步,测试事件是否恰好引发一次:
// Arrange
var eventRaiser = new EventRaiserClass();
int eventRaisedCount = 0;
eventRaiser.SendEventToClient += (o, e) => eventRaisedCount++;
var processRequest = new ProcessRequest(eventRaiser);
// Act
processRequest.Process(someJObject);
// Assert
Assert.Equal(1, eventRaisedCount);
如果你不想依赖 EventRaiserClass
并且你正在使用模拟框架,你可以这样做(我在这个例子中使用 Moq):
// Arrange
var eventRaiser = Mock<IEventRaiser>();
var processRequest = new ProcessRequest(eventRaiser.Object);
// Act
processRequest.Process(someJObject);
// Assert
eventRaiser.Verify(x => x.RaiseEventForClient());
同样使用NSubstitute :
// Arrange
var eventRaiser = Substitute.For<IEventRaiser>();
var processRequest = new ProcessRequest(eventRaiser);
// Act
processRequest.Process(someJObject);
// Assert
eventRaiser.Received().RaiseEventForClient();
作为单独的注释,请考虑一下如何命名类。大多数编码标准规定类应该使用名词 或名词短语 命名,并且不应以“Class”结尾。
所以Client
没问题,但是EventRaiserClass
以Class
结尾。考虑像 EventRaiser
这样的东西。
ProcessRequest
不是名词或名词短语——它听起来像一条指令(“处理此请求”),这通常是您命名方法而非类的方式。考虑像 RequestProcessor
这样的东西,它是一个处理请求的对象。
关于c# - 如何对被测类引发的事件进行单元测试?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58482360/