如果流是基于C#的事件,如何使用单元测试来测试功能?

时间:2019-05-17 06:55:23

标签: c# unit-testing rhino-mocks

我正在为基于事件的流编写单元测试。让我告诉您代码的完整流程。我有一个应用程序App1,它向App2发送一些命令(一种方式)。然后,App2在一段时间后发送事件作为响应。不清楚? 让我们简化一下。我有一个App1,该App1允许用户选择一些商品,完成选择后,用户保留所选商品,这样其他用户就无法选择这些商品。为了保留商品,App1向App2发送命令以逐一保留商品。如果有3种商品,则App1将good1发送到App2进行保留,当收到来自App2的事件时,App1将发送下一个good2进行保留,然后该过程再次进行,直到保留了所有商品。我已经实现了此功能,现在该为它编写单元测试了,但不确定如何处理。文本太多,让我们看一些代码。

 public void ReserveGoods(List<Goods> items)
        {
            //Goods recived from GUI;
            if (items.Count > 0)
            {
                var item = items.First();
                //_agent is nothing but a class to communicate with App2
                _agent.ReserveGood(item.SectNo);
                //After this method, On GUI the status of process is pending unit the else part not run.
            }
            else
            {
                NotifyToGui(Response.GoodsReserved);
            }


        }

        //Event recived from App2
        private void ReadyToProcessNextGood(object sender, ReadyToStartNewGoodItemEventArgs e)
        {
            var processId = e.ProcessId;
            //Remove reserved good.
            _ItemRepository.Delete(e.SectNo);
            var items = _ItemRepository.GetGoodsByProcessId(processId);

            //Going to reserve remaining items
            ReserveGoods(items);
    }

我想为此流程编写单元测试。我可以嘲笑_agent.ReserveGood(item.SectNo)方法,就像我调用事件ReadyToProcessNextGood一样,但是在调用之后,如何进入ReadyToProcessNextGood事件。

1 个答案:

答案 0 :(得分:1)

我将其分为两部分。

  1. 使用适当的单元测试/集成测试来测试业务功能
  2. 使用集成测试来测试整个事情。

我要这样做的方式是这样的:

首先进一步分解代码,从其中删除事件部分。像这样:

 private void ReadyToProcessNextGood(object sender, ReadyToStartNewGoodItemEventArgs e)
    {
            //maybe some checks here to make sure you have the right data
            BusinessMethodHere(e.processId, e.SectNo);
    }

public void BusinessMethodHere( string processId, string sectNo )
{
            //Remove reserved good.
            _ItemRepository.Delete(sectNo);
            var items = _ItemRepository.GetGoodsByProcessId(processId);

            //Going to reserve remaining items
            ReserveGoods(items);
}

现在,您可以在事件调用之外单独测试业务功能。 保持与业务的脱钩,并进行正确的测试。

最后创建一个实际依赖事件的集成测试,并确保该事件正确地流经系统。那时,您不需要测试业务功能,因为您已经使用单元测试/其他集成测试完成了该功能。