繁体   English   中英

如何对被测 class 引发的事件进行单元测试?

[英]How do I unit test the event raised by class under test?

我有下面的 class 负责根据某些业务条件引发事件。

public class EventRaiserClass : IEventRaiserClass 
{
    public event EventHandler SendEventToClient;

    public void RaiseEventForClient()
    {
        SendEventToClient?.Invoke(this, EventArgs.Empty);
    }
}

这是我的客户 class

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被注入到class下面,负责处理一些订单

public class ProcessRequest: IProcessRequest
{
    IEventRaiserClass _evntRaiser;
    public ProcessRequest(IEventRaiserClass evntRaiser)
    {
        _evntRaiser = evntRaiser;
    }

    public void Process(JObject json)
    {
        _evntRaiser.RaiseEventForClient(); 
    }
}

现在,我如何对上述Process方法进行单元测试? 如何确保在调用process方法时引发事件?

据我所知, Client class 与这个问题无关? 您只想测试调用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);

您可以进一步 go 并测试事件是否仅引发一次:

// 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并且您正在使用 mocking 框架,您可以执行以下操作(我在此示例中使用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();

作为单独的说明,请考虑一下如何命名类。 大多数编码标准都规定类应该使用名词名词短语来命名,并且不应以“类”结尾。

所以Client没问题,但是EventRaiserClassClass 考虑类似EventRaiser的东西。

ProcessRequest不是名词或名词短语——它听起来像一个指令(“处理此请求”),这通常是您命名方法的方式,而不是 class。 考虑类似RequestProcessor的东西,它是一个处理请求的 object。

您可能还想检查有关sendereventArgs的抛出事件。 如果您不想编写三个测试方法来测试整个事件引发过程,那么Nuclear.Test适合您。

[TestMethod]
void TestProcessRaisesEvent() {

    // arrange
    var eventRaiser = new EventRaiserClass();
    var processRequest = new ProcessRequest(eventRaiser);
    var json = default(JObject); // create your json
    Action action = () => processRequest.Process(json);

    // act / assert
    Test.If.RaisesEvent(eventRaiser, "SendEventToClient", action, out Object sender, out EventArgs e);
    Test.If.ReferencesEqual(eventRaiser, sender);
    Test.If.ValuesEqual(e, EventArgs.Empty);

}

但是,您应该考虑分别测试EventRaiserClassProcessRequest

[TestMethod]
void TestEventRaiserRaisesEvent() {

    // arrange
    var eventRaiser = new EventRaiserClass();
    Action action = () => eventRaiser.RaiseEventForClient();

    // act / assert
    Test.If.RaisesEvent(eventRaiser, "SendEventToClient", action, out Object sender, out EventArgs e);
    Test.If.ReferencesEqual(eventRaiser, sender);
    Test.If.ValuesEqual(e, EventArgs.Empty);

}

[TestMethod]
void TestProcessRaisesEvent() {

    // arrange
    var eventRaiser = new EventRaiserClass();
    var processRequest = new ProcessRequest(eventRaiser);
    var json = default(JObject); // create your json
    Action action = () => processRequest.Process(json);

    // act / assert
    Test.If.RaisesEvent(eventRaiser, "SendEventToClient", action, out Object sender, out EventArgs e);

}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM