gpt4 book ai didi

c# - 应该如何使具有依赖关系的类可以单元测试而不会膨胀?

转载 作者:行者123 更新时间:2023-11-30 23:11:04 24 4
gpt4 key购买 nike

所以我有一个促进双向 TCP 通信的类(库的一部分)。其中一部分是接受传入连接。

我的实现包括使用 TCPListener 对象和多线程方法来接受连接。为了使其可测试,我决定创建一个“INetworkListener”接口(interface),它只包含一个事件“OnClientAccepted”。这样,我可以使用依赖注入(inject)来模拟 TCPListener 的伪造版本并避免多线程单元测试。

问题是我需要一种方法来使用伪造的 INetworkListener 来测试该类,但我希望我的用户可以选择使用此接口(interface)的其他实现。

这是一些精简的示例代码:

class TcpMessenger
{
// Various properties

private INetworkListener _tcpListener;

public TcpMessenger(int port, string friendlyName) // This is the ONLY constructor I want available to users
{
ServerPort = port;
FriendlyName = friendlyName;
_isRunning = false;
_tcpListener = new ConcreteExample(port); // This prevents unit testing because it opens threads and such
}

public TcpMessenger(int port, string friendlyName, INetworkListener listener) // I need this to test
{
ServerPort = port;
FriendlyName = friendlyName;
_isRunning = false;
_tcpListener = listener; // No dependency here :)
}
}

为什么我不能只保留两个构造函数?

我的图书馆就像一个门面。它使 TCP 通信更容易,但没有增加太多功能。因此,我的目标受众永远不需要注入(inject)这种依赖性。如果我不希望他们这样做,那么适当的设计会告诉我强制执行。

为什么不将其作为面向公众的 API 进行测试?集成测试!

我实际上是用我的库的一个以前版本做的,它是非常耦合的。结果很糟糕。我进行了十几个涉及多线程的测试,更糟糕的是,实际的套接字。单元测试不应该依赖于这样的外部因素。

你真的需要测试这个吗?

是的。该库具有高级功能,例如异常处理、错误报告、连接问题的故障保护以及维护双向连接的算法(意味着每个节点都是客户端和服务器)。可以在不打开实际套接字的情况下测试此功能,所以我绝对想要它。

我还希望单元测试公开。这意味着任何人都可以获取源代码、运行它们并查看所有绿色复选标记。

结论性问题:

我如何独立测试两个类,同时在现实场景中强制依赖?

最佳答案

您可以使用 InternalsVisibleTo 将您的构造函数设为内部并将您的内部结构暴露给您的测试:

[assembly: InternalsVisibleTo("YourNamespace.YourTests")]

参见:https://msdn.microsoft.com/en-us/library/system.runtime.compilerservices.internalsvisibletoattribute(v=vs.110).aspx

关于c# - 应该如何使具有依赖关系的类可以单元测试而不会膨胀?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44992101/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com