C#:从测试方法调用时方法失败,否则工作正常

时间:2017-07-31 20:30:23

标签: c# unit-testing azure azure-sql-database

当我从代码中的其他地方调用它时,我的方法工作正常,我添加了单元测试来测试这个方法,当它从测试方法调用时,它会在第一行引发异常。

    public static void PostToAzureQueue(AlertNotification alertNotification)
    {
        CloudStorageAccount storageAccount = CloudStorageAccount.Parse(CloudConfigurationManager.GetSetting("StorageConnectionString"));
        CloudQueueClient queueClient = storageAccount.CreateCloudQueueClient();
        CloudQueue queue = queueClient.GetQueueReference("activealertsqueue");
        queue.CreateIfNotExists();
        CloudQueueMessage message = new CloudQueueMessage(alertNotification.Serialize());
        queue.AddMessage(message);
    }

这是测试方法

    public void VerifyPostToAzureQueue()
    {
        try
        {
            AlertNotification alertNotification = new AlertNotification();
            alertNotification.DataCenters = "TestCenter";
            alertNotification.TimeStamp = DateTime.Now;
            Utils.PostToAzureQueue(alertNotification);

            Assert.IsTrue(true);
        }
        catch
        {
            Assert.Fail();
        }
    }

当我在方法的第一行硬编码连接字符串时,它传递了这一行但在第二行中失败了。 当我从其他地方调用它时,该方法工作得很好。 请注意,测试方法是在单独的测试项目中。

1 个答案:

答案 0 :(得分:5)

根据您上面的评论,您会看到一个空引用异常,因为您的代码可能是这一行:

CloudStorageAccount.Parse(CloudConfigurationManager.GetSetting("StorageConnectionString"))

无法找到连接字符串。如您所述,您的测试函数与生产代码位于一个单独的项目中,因此StorageConnectionString可能不在可访问的配置文件中。

很好地说明了为什么在你要使用它的代码中构建连接对象是个坏主意。您当前的PostToAzureQueue方法会执行多项操作:

  1. 它会为您的帐户设置连接设置。
  2. 它会为您的帐户创建一个客户端。
  3. 如果不存在,则会创建activealertsqueue
  4. 它向该队列发送消息。
  5. 这违反了Single Responsibility Principle。此方法应该做一件事:将消息发送到队列。您应该重构此方法以仅执行该操作,然后为其提供执行该操作所需的工具。所以它看起来像:

    public static void PostToAzureQueue(AlertNotification alertNotification, CloudQueueClient client)
    {
        var queue = client.GetQueueReference("activealertsqueue");
        queue.AddMessage(new CloudQueueMessage(alertNotification.Serialize()));
    }
    

    您的客户端应该在外部创建并injected到您的代码中(实际上它应该被注入到父类而不是这个方法中,但这是一个不同的讨论)。然后,您可以处理任何异常(例如,QueueNotExists或在activealertsqueue不存在时将抛出的任何异常)并重试调用PostToAzureQueue的逻辑。通过从此方法中提取这些功能,您将简化此方法并使其更易于测试。