1

I have a WPF window which simply displays statis data, along with the computer's active IPv4 addresses. When constructed, the ViewModel calls the following code (in a separate thread):

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 is bound to a control in the view, and that's it.

I'm wondering if I should unit test this code. This is more of an integration test, but even then I wouldn't know how to fake having/not having an active IPv4 address.

But if I do want to unit test this, how would I mock the static method calls to the .Net framework (e.g. NetworkInterface.GetIsNetworkAvailable())?

I could create my own wrapper class that simply calls the static methods, extract an interface and create a mock. But if I take that strategy further into the rest of my application, I'll be creating quite a few redundant wrapper around the .Net framework.

I could also have the method GetIpAddresses take in two delegates, one that returns the answer to "is network available" and another one that returns all network interfaces. But then the real caller of this method would have to practically pass GetIpAddresses half of its logic, and that breaks the whole idea of separation of concerns... doesn't it?

user884248
  • 2,134
  • 3
  • 32
  • 57

1 Answers1

2

You probably shouldn't unit test this as it currently stands; there is a single line that is unit-test worthy (because everything else is the .Net framework)

resultList.AddRange(from address in item.GetIPProperties().UnicastAddresses
                        where address.Address.AddressFamily == AddressFamily.InterNetwork
                        select address.Address.ToString());

And the test would literally be to ensure that you add whatever addresses are found to the list that's going to be returned

To do that you'll need to make this method a query that returns the list(i.e. so that you can verify that the correct values are returned) and also make it public so you can test it; and yes, you will need to create a wrapper around the framework calls.

But is that worth the trouble in this case? I don't think so.

However.

I would say it is worth the trouble to move this from being a private method, to a separate dependency (e.g. INetworkAddressLister with method IEnumerable<string> GetNetworkAddresses()) that you inject into whatever class consumes it. Then you can at least Mock or Stub it when you are testing the consumer.

You say that this is bound directly to a control in the UI, which is one consumer, but there is another consumer at play here - the unit tests of the class that contains this code, and which should be the first consumer of it :)

Community
  • 1
  • 1
Stephen Byrne
  • 7,400
  • 1
  • 31
  • 51