C#:我应该单元测试一个依赖于.Net Framework静态方法的方法,如果是的话 - 如何?

时间:2016-10-05 06:17:17

标签: .net unit-testing

我有一个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的一半逻辑传递给它,这打破了关注点分离的整个想法......不是吗?

1 个答案:

答案 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中的控件,这是一个消费者,但是还有另一个消费者在这里 - 包含此代码的类的单元测试,以及应该是它的第一个消费者:)