如何集成测试Azure Web作业?

时间:2016-09-02 19:52:11

标签: azure integration-testing azure-storage azure-webjobs

我有一个支持Azure Web Job的ASP.NET Web API应用程序,其功能由API控制器添加到存储队列的消息触发。使用OWIN测试Web API很简单,但如何测试Web作业?

我是否在测试运行器中运行内存中的控制台应用程序?直接执行该功能(虽然这不是一个合适的集成测试)?这是一项持续的工作,因此应用程序不会退出。更糟糕的是,Azure Web Job-functions无效,因此没有输出断言。

3 个答案:

答案 0 :(得分:3)

无需在内存中运行控制台应用程序。您可以在集成测试的内存中运行JobHost。

var host = new JobHost();

您可以使用host.Call()或host.RunAndBlock()。您需要指向Azure存储帐户,因为localhost不支持webjobs。 这取决于您的功能正在做什么,但您可以手动将消息添加到队列,添加blob或其他任何内容。您可以通过查询webjob执行结果的存储等来断言

答案 1 :(得分:2)

虽然@ boris-lipschitz是正确的,但是当你的工作是连续的时(正如操作所说的那样),你在调用host.RunAndBlock()之后就无法做任何事情。

但是,如果您在单独的线程中运行主机,则可以根据需要继续进行测试。虽然,您必须在测试结束时进行某种轮询,以了解作业何时运行。

示例
要测试的函数(从一个blob到另一个blob的简单复制,由创建的blob触发):

public void CopyBlob(
    [BlobTrigger("input/{name}")] TextReader input,
    [Blob("output/{name}")] out string output)
{
    output = input.ReadToEnd();
}

测试功能:

[Test]
public void CopyBlobTest()
{
    var blobClient = GetBlobClient("UseDevelopmentStorage=true;");

    //Start host in separate thread
    var thread = new Thread(() =>
    {
        Thread.CurrentThread.IsBackground = true;
        var host = new JobHost();
        host.RunAndBlock();
    });

    thread.Start();

    //Trigger job by writing some content to a blob
    using (var stream = new MemoryStream())
    using (var stringWriter = new StreamWriter(stream))
    {
        stringWriter.Write("TestContent");
        stringWriter.Flush();

        stream.Seek(0, SeekOrigin.Begin);

        blobClient.UploadStream("input", "blobName", stream);
    }

    //Check every second for up to 20 seconds, to see if blob have been created in output and assert content if it has
    var maxTries = 20;
    while (maxTries-- > 0)
    {
        if (!blobClient.Exists("output", "blobName"))
        {
            Thread.Sleep(1000);
            continue;
        }

        using (var stream = blobClient.OpenRead("output", "blobName"))
        using (var streamReader = new StreamReader(stream))
        {
            Assert.AreEqual("TestContent", streamReader.ReadToEnd());
        }
        break;
    }
}

答案 2 :(得分:0)

我已经能够通过简单地执行以下操作来轻松地模拟这一点,它似乎对我来说很好:

private JobHost _webJob;

[OneTimeSetUp]
public void StartupFixture()
{
     _webJob = Program.GetHost();
     _webJob.Start();
}
[OneTimeTearDown]
public void TearDownFixture()
{
    _webJob?.Stop();
}

WebJob代码如下所示:

public class Program
{
    public static void Main()
    {
        var host = GetHost();
        host.RunAndBlock();
    }

    public static JobHost GetHost() 
    {
        ...
    }
}