我正在为一个新的应用程序构建一个可以称为 DAL 的东西。不幸的是,与数据库的网络连接是一个真正的问题。
我希望能够在我的测试范围内临时阻止网络访问,以便我可以确保我的 DAL 在这些情况下按预期运行。
更新:有很多手动方法可以禁用网络,但如果我可以在测试本身中启用/禁用它肯定会很好。
我正在为一个新的应用程序构建一个可以称为 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 之类的 Mock 框架在测试中模拟异常。这是您在测试中可能拥有的一些伪代码
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
使用模拟对象创建真实事物的可配置、可破坏版本——在本例中为数据库。