我有一个C#模块,负责获取Windows Vista计算机上“连接到互联网”的网络适配器列表。该模块使用“Network List Manager API”(或NLM API)迭代所有网络连接,并返回IsConnectedToInternet值为true的所有连接。
我在此SO question
中收到了有关此模块实施的一些建议为了测试这个模块,我决定编写一个帮助器,它根据另一个逻辑返回互联网连接接口列表,因此它将是原始模块逻辑的一种“现实检查”。请注意,对于测试助手,我愿意使用可能被视为生产代码不良做法的检测方法(例如,依赖某些互联网资源,如“Google”可用 - 如果它关闭,被我们的内部防火墙阻止等。与部署的产品基础相比,修复测试相对容易。)
我选择的替代检测方法是尝试使用TcpClient连接到“www.google.com:80”。我的问题:当我有多个连接的适配器(例如无线和LAN)时,其中一个的检测方法失败,并显示错误“已在连接的套接字上发出连接请求”。
我的问题有三个:
您将如何进行一般的测试?你是否支持以不同的方式做同样的事情并比较结果的想法,或者它是否过度,我应该依赖系统的API?我的主要问题是,预先配置系统非常困难,以便我能提前知道预期的结果。
您会建议哪种替代逻辑?在上述问题中提出的一件事是查看路由表 - 如果考虑每个具有目标为0.0.0.0的路由条目的适配器作为“连接到互联网”?其他建议?
您是否理解为什么我使用当前测试逻辑出现“已连接”错误?
答案 0 :(得分:4)
我只能回答你关于单元测试的问题。
您正在测试的代码,用您自己的话说,“负责获取Windows Vista计算机上”连接到互联网“的网络适配器列表的C#模块。该模块使用'网络列表管理器API'(或NLM API)迭代所有网络连接并返回IsConnectedToInternet值为true的所有连接。“
如果我正在编写此模块,我将首先使用NLM API的接口,将其命名为... NLMAPIService。现在,对于真实代码,创建一个实现NLMAPIService的适配器并调整真正的NLM API。
为了进行测试,创建一个实现NLMAPIService的类FakeNLMAPI,并将其所有数据存储在某个位置,或者存储在XML文件中,或者其他任何内容中。您的模块仅在NLMAPIService上调用方法,因此您无需更改任何“真实”代码,具体取决于您是否正在测试。
因此,在您的测试设置方法中,您可以实例化FakeNLMAPI并将其传递给您的模块,并在生产中实例化您的NLM API适配器。
我将假设您可以实例化和修改代表网络连接的对象。如果没有,您可以按照相同的模式伪造实际的网络连接对象。
答案 1 :(得分:2)
依赖注入是处理这类问题的一种非常方便的模式。不是直接在代码中直接使用NLM API组件,而是定义一个接口和一个实现它的类,并充当NLM API的代理。将此类的实例传递给构造函数中的模块,并让模块使用它。在单元测试中,使用一个模拟对象而不是真正的代理对象,使用模拟对象返回已知信息 - 它甚至不必引用NLM API - 用于测试模块的逻辑。当然,您的代理类也需要一些测试,但其中的逻辑要简单得多 - 可能只是一些数据封送。您可能能够说服自己的正确性,如果没有,请对其进行一些手动测试以确保其正常工作。
答案 2 :(得分:0)
UnitTests不应该访问外部资源。对于UnitTest您的方法,我将存根网络列表管理器API。
您仍需要验收测试图层。在该测试环境中,您应该复制您希望在您的环境中支持的各种配置,设置您自己的webhost,路由器,机器配置。验收测试应使用Fitnesse等工具在用户体验级别完成。