为什么单元测试时azure存储队列访问速度如此之慢?

时间:2013-05-29 21:14:38

标签: unit-testing azure-storage vs-unit-testing-framework azure-storage-queues

我在尝试使用实时Azure存储队列进行单元测试时遇到了一些困难,并且一直在编写更简单,更简单的示例来尝试隔离问题。简而言之,这就是正在发生的事情:

  • 队列访问显然(并且适当地)延迟加载。在我的MVC应用程序中,当我真正需要访问队列时(在我调用CloudQueue.Exists方法的情况下),它非常快。不到十分之一秒。但是,在单元测试的上下文中运行时,非常相同的代码大约需要25秒。

  • 我不明白为什么会出现这种差异,所以我制作了一个简单的控制台应用程序来编写内容,然后从Azure队列中读取它。控制台应用程序在第一次运行时也需要25秒 - 在后续运行时大约需要2.5秒。

  • 现在真的很奇怪了。我创建了一个包含三个项目的Visual Studio 2012解决方案 - 一个MVC应用程序,一个Console应用程序和一个Unit Test项目。所有这三个调用相同的静态方法来检查队列的存在,如果它不存在则创建它,向它写入一些数据并从中读取一些数据。我已经在该方法中调用了CloudQueue.Exists的计时器。这是交易。当从MVC应用程序调用该方法时,无论队列是否确实存在,CloudQueue.Exists方法都会在大约十分之一秒内始终完成。从控制台应用程序调用该方法时,第一次调用它需要25秒,随后需要大约2.5秒。当从单元测试中调用该方法时,它始终需要25秒。

  • 更多信息:当我创建这个虚拟解决方案时,我碰巧将我的静态方法(QueueTest)放在控制台应用程序中。这有点奇怪 - 如果我将Visual Studio中的默认启动项目设置为Console App,那么单元测试突然需要2.5秒。但是,如果我将Visual Studio中的启动项目设置为MVC应用程序(或单元测试项目),则单元测试需要25秒!

所以....有没有人有关于这里发生了什么的理论?我很困惑。

代码如下:

控制台应用

public class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine(QueueTest("my-console-queue", "Console Test"));
    }

    public static string QueueTest(string queueName, string message)
    {
        string connectionString = ConfigurationManager.ConnectionStrings["StorageConnectionString"].ConnectionString;

        CloudStorageAccount storageAccount = CloudStorageAccount.Parse(connectionString);

        CloudQueueClient queueClient = storageAccount.CreateCloudQueueClient();

        CloudQueue queue = queueClient.GetQueueReference(queueName);

        DateTime beforeTime = DateTime.Now;
        bool doesExist = queue.Exists();
        DateTime afterTime = DateTime.Now;
        TimeSpan ts = afterTime - beforeTime;

        if (!doesExist)
        {
            queue.Create();
        }

        CloudQueueMessage qAddMessage = new CloudQueueMessage(message);

        queue.AddMessage(qAddMessage);

        CloudQueueMessage qGetmessage = queue.GetMessage();

        string response = String.Format("{0} ({1} seconds)", qGetmessage.AsString, ts.TotalSeconds);

        return response;
    }
}

MVC App(家庭控制器):

public class HomeController : Controller
{
    public ActionResult Index()
    {
        return Content(Program.QueueTest("my-mvc-queue", "Mvc Test"));
    }
}

单位测试方法:(注意,目前预计会失败!)

[TestClass]
public class QueueUnitTests
{
    [TestMethod]
    public void CanWriteToAndReadFromQueue()
    {
        //Arrange
        string qName = "my-unit-queue";
        string message = "test message";

        //Act
        string result = Program.QueueTest(qName, message);

        //Assert
        Assert.IsTrue(String.CompareOrdinal(result,message)==0);
    }
}

当然,非常感谢洞察力。

1 个答案:

答案 0 :(得分:1)

我怀疑这与Azure队列无关,而是与.NET试图确定您的代理设置。如果您进行其他随机System.Net调用而不是调用队列存储会发生什么?

在应用的开头试用这行代码:

   System.Net.WebRequest.DefaultWebProxy = null;