正确的单元测试私有变量的方法

时间:2010-09-07 19:41:20

标签: unit-testing mocking mstest

我有以下方法:

private string _google = @"http://www.google.com";

public ConnectionStatus CheckCommunicationLink()
{
    //Test if we can get to Google (A happy website that should always be there).
    Uri googleURI = new Uri(_google);
    if (!IsUrlReachable(googleURI, mGoogleTestString))
    {
        //The internet is not reachable.  No connection is available.
        return ConnectionStatus.NotConnected;
    }

    return ConnectionStatus.Connected;
}

问题是,如何让它不尝试与谷歌的连接(从而避免依赖互联网)。

最简单的方法是取_google并将其更改为指向机器本地的某些内容。但要做到这一点,我需要_google public。我宁愿不这样做,因为应用程序不应该更改_google

我可以让`_google'成为方法(或对象构造函数)的重载版本的参数。但是,这也暴露了我不希望应用程序使用的界面。

另一种选择是_google internal。但对于该应用,internalpublic相同。因此,虽然其他人看不到_google,但应用程序界面仍然会公开它。

有更好的方法吗?如果是,请说明。

(另外,请不要选择我的例子,除非它真的有助于找出解决方案。我在这样的一般情况下提出想法,不一定是这个确切的例子。)

4 个答案:

答案 0 :(得分:1)

重构代码以依赖ICommunicationChecker:

public interface ICommunicationChecker
{
    ConnectionStatus GetConnectionStatus();
}

然后你的测试可以模拟这个接口,使实现细节无关紧要。

public class CommunicationChecker : ICommunicationChecker
{
    private string _google = @"http://www.google.com";

    public ConnectionStatus GetConnectionStatus()
    {
        //Test if we can get to Google (A happy website that should always be there).
        Uri googleURI = new Uri(_google);
        if (!IsUrlReachable(googleURI, mGoogleTestString))
        {
            //The internet is not reachable.  No connection is available.
            return ConnectionStatus.NotConnected;
        }

        return ConnectionStatus.Connected;
    }
}

答案 1 :(得分:0)

为什么您的代码中有_google硬编码?为什么不把它放在一个配置文件中,然后你可以为测试更改它?

答案 2 :(得分:0)

一些选项:

  • 从外部配置加载_google(可能提供www.google.com作为默认值)并为单元测试提供特殊配置;
  • 将单元测试类放在包含CheckCommunicationLink方法的类中。

注意:我强烈建议将其配置为可配置。在实际情况下,依赖于特定第三方网站的可用性并不是一个好主意,因为它们可能被本地防火墙等阻止。

答案 3 :(得分:0)

对于单元测试目的,您应该模拟您在班级中使用的任何http连接(隐藏在IsUrlReachable方法中)。这样,您可以检查您的代码是否真的尝试连接到谷歌而不实际连接。如果您需要更多关于模拟的帮助,请粘贴IsUrlReachable方法。

如果上述解决方案不是一个选项,您可以考虑使用本地测试http服务器并且:

  1. 使网址可配置,以便您可以指向本地地址
  2. (这个很讨厌)使用反射在测试之前更改_google
  3. (大多数纯粹主义者在这里不同意)你可以创建一个带参数的重载并使用这个参数进行测试(所以你只测试CheckCommunicationLink(string url)方法
  4. 代码(3):

    private string _google = @"http://www.google.com";
    
    public ConnectionStatus CheckCommunicationLink()
    {
        return CheckCommunicationLink(_google);
    }
    
    public ConnectionStatus CheckCommunicationLink(string url)
    {
        //Test if we can get to Google (A happy website that should always be there).
        Uri googleURI = new Uri(url);
        if (!IsUrlReachable(googleURI, mGoogleTestString))
        {
            //The internet is not reachable.  No connection is available.
            return ConnectionStatus.NotConnected;
        }
    
        return ConnectionStatus.Connected;
    }
    
相关问题