识别实体模式以抽象网络层以允许可测试性

时间:2013-02-16 17:14:43

标签: c# networking mocking

我在这里读过关于

这个论点的各种问题

How do you unit-test a TCP Server? Is it even worth it?

和其他更具体的问题

Has anyone successfully mocked the Socket class in .NET?

rhino mocks: how to build a fake socket?

但我总是想发布这个问题。

我需要设计一个抽象网络层。将消费者代码与特定实现相结合应该是抽象的,最后但并非最不重要的是,可以用假货完全测试。

我最终认为我不需要模拟Socket类,而是定义更高级别的抽象并模拟它。

interface INetworkLayer {
  void OnConnect(Stream netwokStream);
  void OnException(Exception e); // doubts on this  
}

有没有人做过接近这个的事情,可以提供观察,评论或解释如何看起来正确的方向?

1 个答案:

答案 0 :(得分:2)

我相信你所要求的不是“提高可测试性”,而只是“测试”通过网络发送内容的代码。

根据我的经验,通过网络发送的内容只有两件有趣的事情需要测试:

  1. 我的申请是否发送了正确的信息?
  2. 我能通过网络发送此消息吗?
  3. 例如,假设您的应用程序可以将一些(应用级别)消息发送到另一台服务器。您可以定义如下界面:

    
    
        public interface MessagePort {
            void Send(Message message, ServerName to);
        }
    
    

    其中Message是您希望应用程序发送的消息,ServerName是表示用于命名消息目标的应用程序级方法的类。为简单起见,ServerName可以是一个简单的字符串,可以通过配置,DNS或其他任何方式映射到服务器的地址。你选择。

    您可以实现MockMessagePort,将消息存储到一个简单的列表中,以测试您的应用程序确实正在发送正确的消息。 (问题1。)

    之后,您可以使用环回通过网络实现实际的消息发送。你可能想读一下Bob叔叔的“Craftsman”文章,作为一个例子。

    http://www.objectmentor.com/resources/publishedArticles.html,主题为“工匠”。 TCP服务器的测试驱动实现是系列中的一些剧集,但您应该从一开始就阅读它。

    更有趣的抽象是消息收件人的“频道”。

    
    
        public interface MessageChannel {
            void Send(Message message);
        }
    
    

    实施知道收件人的地方。当然,在这种情况下,还有另一个对象提供频道,来自收件人“ServerName”。

    如果您真的想拥有网络设施的抽象模型,那么您可以做以下事情:

    1. 尝试找到两个不同的网络库。
    2. 使用每个库编写同一个应用程序两次。
    3. 考虑应用程序因素。应用代码应该相同,网络部分应该有所不同。它们将由界面分隔。这是您正在寻找的界面。
    4. 但老实说,我认为它不会给你的申请带来太大的影响。