如何为测试目的模拟网络故障(在C#中)?

我正在构建一个可以称为DAL的新应用程序。 不幸的是,与数据库的网络连接是一个真正的问题。

我希望能够在我的测试范围内暂时阻止网络访问,以便我可以确保我的DAL在这些情况下按预期运行。

更新:有许多手动方式来禁用网络,但如果我可以在测试本身内启用/禁用它肯定会很好。

目前,我只是通过设置虚假静态IP来“禁用”网络,如下所示:

using System.Management; class NetworkController { public static void Disable() { SetIP("192.168.0.4", "255.255.255.0"); } public static void Enable() { SetDHCP(); } private static void SetIP(string ip_address, string subnet_mask) { ManagementClass objMC = new ManagementClass("Win32_NetworkAdapterConfiguration"); ManagementObjectCollection objMOC = objMC.GetInstances(); foreach (ManagementObject objMO in objMOC) { if ((bool)objMO("IPEnabled")) { try { ManagementBaseObject setIP = default(ManagementBaseObject); ManagementBaseObject newIP = objMO.GetMethodParameters("EnableStatic"); newIP("IPAddress") = new string[] { ip_address }; newIP("SubnetMask") = new string[] { subnet_mask }; setIP = objMO.InvokeMethod("EnableStatic", newIP, null); } catch (Exception generatedExceptionName) { throw; } } } } private static void SetDHCP() { ManagementClass mc = new ManagementClass("Win32_NetworkAdapterConfiguration"); ManagementObjectCollection moc = mc.GetInstances(); foreach (ManagementObject mo in moc) { // Make sure this is a IP enabled device. Not something like memory card or VM Ware if ((bool)mo("IPEnabled")) { ManagementBaseObject newDNS = mo.GetMethodParameters("SetDNSServerSearchOrder"); newDNS("DNSServerSearchOrder") = null; ManagementBaseObject enableDHCP = mo.InvokeMethod("EnableDHCP", null, null); ManagementBaseObject setDNS = mo.InvokeMethod("SetDNSServerSearchOrder", newDNS, null); } } } } 

写一个包装器到你正在使用的网络类连接类(例如WebClient)和一个开关:)

要么是这样,要么阻止你的应用程序在防火墙中。

如果您正在为应用程序尝试完全网络中断,则可以拔掉网络电缆。 有时您可能拥有一个包含多个数据源的数据访问层(在不同的计算机上),在这种情况下,您可以使用像Rhino Mocks这样的模拟框架模拟测试中的exception。 以下是您在测试中可能遇到的一些伪代码

 void TestUserDBFailure() { // ***** THIS IS PSEUDO-CODE ******* //setting up the stage - retrieval of the user info create an exception Expect.Call(_userRepository.GetUser(null)) .IgnoreArguments() .Return(new Exception()); // Call that uses the getuser function, see how it reacts User selectedUser = _dataLoader.GetUserData("testuser", "password"); } 

尝试在会话中途阻止与防火墙的连接?

我也喜欢包装器的想法,但这有点抽象问题而且你可能不会得到确切的真实世界行为。 此外,插入包装层然后将其移除可能比其价值更麻烦。

编辑 :运行一个脚本,可以随机或按设定的时间间隔打开/关闭网络适配器?

尝试Toxiproxi,它可以模拟网络中断。

他们有REST API甚至.NET Client API以编程方式(从您的测试代码)更改网络模拟https://github.com/shopify/toxiproxy

寻找一个可以限制带宽的WAN模拟器(并完全切断它)我总是觉得有趣的是看看当我的应用在带宽受限的环境中运行时用户体验如何变化。 在这里查看一些信息。

如本博客文章中所述,您可以使用一种工具来模拟数据库应用程序测试中的高延迟和低带宽。

可能对模拟“真实”网络问题没有帮助,但您可以在测试范围内将数据库连接字符串指向不存在的计算机。

取决于您希望模拟的特定网络问题。 对于大多数人来说,它就像“服务器无法访问”一样简单,在这种情况下,您只是尝试连接到不存在的服务器。 但要小心,因为你想要一些可以路由但却没有回答的东西。 尝试连接到dkjdsjk.com将立即失败(DNS查找),但尝试连接到www.google.com:1433将(可能)由于防火墙而超时 – 这是您的数据库服务器时应用程序的行为方式下。

刚刚找到一个允许直接关闭TCP连接的替代方案:

http://lamahashim.blogspot.ch/2010/03/disabling-network-using-c.html

它基于Windows IP Helper API(使用DllImport): http : //msdn.microsoft.com/en-us/library/windows/desktop/aa366073 (v = vs。85) .aspx

使用模拟对象创建可配置的,可破坏的真实版本 – 在本例中为数据库。