我有一个WPF窗口,它只显示statis数据以及计算机的活动IPv4地址。构造时,ViewModel调用以下代码(在单独的线程中):
private void GetIpAddresses()
{
var resultList = new List<string>();
if (NetworkInterface.GetIsNetworkAvailable() != false)
{
foreach (var item in NetworkInterface.GetAllNetworkInterfaces())
{
if (item.NetworkInterfaceType != NetworkInterfaceType.Loopback &&
item.OperationalStatus == OperationalStatus.Up)
{
resultList.AddRange(from address in item.GetIPProperties().UnicastAddresses
where address.Address.AddressFamily == AddressFamily.InterNetwork
select address.Address.ToString());
}
}
}
IpAddresses = FormatIpAddresses(resultList);
}
IpAddresses绑定到视图中的控件,就是这样。
我想知道我是否应该对此代码进行单元测试。这更像是一个集成测试,但即便如此,我也不知道如何伪造/没有活动的IPv4地址。
但是如果我想对这个进行单元测试,我将如何模拟对.Net框架的静态方法调用(例如NetworkInterface.GetIsNetworkAvailable())?
我可以创建自己的包装类,只需调用静态方法,提取接口并创建模拟。但是,如果我将该策略进一步应用到我的应用程序的其余部分,我将围绕.Net框架创建相当多的冗余包装。
我还可以使用方法GetIpAddresses接收两个委托,一个返回“是网络可用”的答案,另一个返回所有网络接口。但是,这种方法的真正调用者必须实际上将GetIpAddresses的一半逻辑传递给它,这打破了关注点分离的整个想法......不是吗?
答案 0 :(得分:2)
你可能不应该像现在这样对它进行单元测试;有一行是单位测试值得的(因为其他一切都是.Net框架)
resultList.AddRange(from address in item.GetIPProperties().UnicastAddresses
where address.Address.AddressFamily == AddressFamily.InterNetwork
select address.Address.ToString());
测试确实是为了确保你在列表中添加任何可以返回的地址
为此,您需要将此方法作为返回列表的查询(即,以便您可以验证是否返回了正确的值)并将其公开以便您可以对其进行测试;是的,您需要围绕框架调用创建一个包装器。
但在这种情况下,这是值得的吗?我不这么认为。
我会说 值得将此从私有方法转移到您注入的单独依赖项(例如INetworkAddressLister
与方法IEnumerable<string> GetNetworkAddresses()
)无论什么阶级消耗它。
然后,当您测试使用者时,您至少可以模拟或存根。
你说这是直接绑定到UI中的控件,这是一个消费者,但是还有另一个消费者在这里 - 包含此代码的类的单元测试,以及应该是它的第一个消费者:)