如何集成测试 Azure Web 作业?
How to integration test Azure Web Jobs?
我有一个 ASP.NET Web API 应用程序支持 Azure Web Job,其功能由 API 的控制器添加到存储队列的消息触发。使用 OWIN 测试 Web API 非常简单,但我该如何测试 Web 作业?
我 运行 测试时内存中的控制台应用程序 运行ner 吗?直接执行函数(虽然这不是一个合适的集成测试)?这是一项持续的工作,因此应用程序不会退出。更糟糕的是,Azure Web 作业函数无效,因此没有要断言的输出。
不需要运行内存中的控制台应用程序。你可以运行JobHost在你集成测试的内存中。
var host = new JobHost();
您可以使用 host.Call() 或 host.RunAndBlock()。您需要指向 Azure 存储帐户,因为本地主机不支持 Web 作业。
这取决于您的功能在做什么,但您可以手动将消息添加到队列、添加 blob 或其他任何内容。您可以通过查询您的 webjob 执行结果的存储等来断言
虽然@boris-lipschitz 是正确的,但如果您的工作是连续的(如 op 所说),您在调用 host.RunAndBlock() 后将无能为力。
但是,如果您 运行 主机在一个单独的线程中,您可以根据需要继续测试。虽然,您必须在测试结束时进行某种轮询才能知道作业何时有 运行.
例子
要测试的函数(从一个 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;
}
}
我已经能够通过简单地执行以下操作非常轻松地模拟这个,它似乎对我来说工作得很好:
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()
{
...
}
}
我有一个 ASP.NET Web API 应用程序支持 Azure Web Job,其功能由 API 的控制器添加到存储队列的消息触发。使用 OWIN 测试 Web API 非常简单,但我该如何测试 Web 作业?
我 运行 测试时内存中的控制台应用程序 运行ner 吗?直接执行函数(虽然这不是一个合适的集成测试)?这是一项持续的工作,因此应用程序不会退出。更糟糕的是,Azure Web 作业函数无效,因此没有要断言的输出。
不需要运行内存中的控制台应用程序。你可以运行JobHost在你集成测试的内存中。
var host = new JobHost();
您可以使用 host.Call() 或 host.RunAndBlock()。您需要指向 Azure 存储帐户,因为本地主机不支持 Web 作业。 这取决于您的功能在做什么,但您可以手动将消息添加到队列、添加 blob 或其他任何内容。您可以通过查询您的 webjob 执行结果的存储等来断言
虽然@boris-lipschitz 是正确的,但如果您的工作是连续的(如 op 所说),您在调用 host.RunAndBlock() 后将无能为力。
但是,如果您 运行 主机在一个单独的线程中,您可以根据需要继续测试。虽然,您必须在测试结束时进行某种轮询才能知道作业何时有 运行.
例子
要测试的函数(从一个 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;
}
}
我已经能够通过简单地执行以下操作非常轻松地模拟这个,它似乎对我来说工作得很好:
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()
{
...
}
}