2

我有一个 C# 模块负责获取 Windows Vista 机器上“连接到互联网”的网络适配器列表。该模块使用“网络列表管理器 API ”(或 NLM API)遍历所有网络连接并返回所有 IsConnectedToInternet 值为 true 的连接。

我收到了一些关于在这个SO question中实施这个模块的建议

为了测试这个模块,我决定编写一个帮助程序,它基于另一个逻辑返回互联网连接的接口列表,因此这将是对原始模块逻辑的一种“现实检查”。请注意,对于测试助手,我愿意使用可能被认为对生产代码不利的检测方法(例如,依赖一些可用的互联网资源,如“Google”——以防它关闭、被我们的内部防火墙阻止等)。与部署的产品库相比,修复测试相对容易)。

我选择的另一种检测方法是尝试使用 TcpClient 连接到“www.google.com:80”。我的问题:当我有多个连接的适配器(例如无线和 LAN)时,其中一个的检测方法失败,并出现错误“在已连接的套接字上发出连接请求”。

我的问题是三个方面:

  1. 一般来说,您将如何测试这样的模块?您是否支持以不同的方式做同样的事情并比较结果的想法,或者这是一种矫枉过正的做法,我应该依赖系统的 API?我在这里的主要问题是,很难预先配置系统,以便我提前知道预期的结果。

  2. 你会建议什么替代逻辑?上述问题中建议的一件事是查看路由表 - 是否将每个具有目的地为 0.0.0.0 的路由条目的适配器视为“已连接到 Internet”?其他建议?

  3. 你明白为什么我在当前的测试逻辑中得到“已经连接”的错误吗?

4

3 回答 3

4

我只能回答你关于单元测试的问题。

用您自己的话来说,您正在测试的代码是“一个 C# 模块,负责获取 Windows Vista 机器上‘连接到互联网’的网络适配器列表。该模块使用‘网络列表管理器 API’(或 NLM API)迭代所有网络连接并返回所有 IsConnectedToInternet 值为 true 的连接。”

如果我正在编写这个模块,我会首先使用 NLM API 的接口,将其命名为...NLMAPIService。现在,对于真实的代码,创建一个实现 NLMAPIService 并适配真实 NLM API 的 Adapter。

为了测试,创建一个实现 NLMAPIService 的 FakeNLMAPI 类,并将其所有数据保存在内存中的某个地方,或者在 XML 文件中,或其他任何地方。您的模块仅在 NLMAPIService 上调用方法,因此您不必根据是否正在测试更改任何“真实”代码。

因此,在您的测试设置方法中,您可以实例化 FakeNLMAPI 并将其传递给您的模块,并在生产中实例化您的 NLM API 适配器。

我将假设您可以实例化和修改表示网络连接的对象。如果没有,您可以按照相同的模式来伪造实际的网络连接对象。

于 2008-10-12T13:40:40.387 回答
2

依赖注入是处理此类问题的一种非常方便的模式。不是简单地在代码中直接使用 NLM API 组件,而是定义一个接口和一个实现它并充当 NLM API 代理的类。在构造函数中将此类的实例传递给您的模块并让您的模块使用它。在您的单元测试中,使用返回已知信息的模拟对象而不是真正的代理对象——它甚至不必引用 NLM API——来用于测试模块的逻辑。当然,您的代理类也需要一些测试,但其中的逻辑要简单得多——可能只是一些数据封送处理。您可能能够说服自己它的正确性,或者,如果不是,则对其进行一些手动测试以确保其正常工作。

于 2008-10-12T13:42:24.220 回答
0

UnitTests 不应访问外部资源。为了对您的方法进行单元测试,我将删除网络列表管理器 API。

您仍然需要一个验收测试层。在该测试环境中,您应该复制您希望在您的环境中支持的各种配置,设置您自己的虚拟主机、路由器、机器配置。验收测试应该使用像 Fitnesse 这样的工具在用户体验级别进行。

于 2008-10-12T13:22:45.740 回答