<bdo id='vZto8'></bdo><ul id='vZto8'></ul>
<legend id='vZto8'><style id='vZto8'><dir id='vZto8'><q id='vZto8'></q></dir></style></legend>

    <small id='vZto8'></small><noframes id='vZto8'>

    <i id='vZto8'><tr id='vZto8'><dt id='vZto8'><q id='vZto8'><span id='vZto8'><b id='vZto8'><form id='vZto8'><ins id='vZto8'></ins><ul id='vZto8'></ul><sub id='vZto8'></sub></form><legend id='vZto8'></legend><bdo id='vZto8'><pre id='vZto8'><center id='vZto8'></center></pre></bdo></b><th id='vZto8'></th></span></q></dt></tr></i><div id='vZto8'><tfoot id='vZto8'></tfoot><dl id='vZto8'><fieldset id='vZto8'></fieldset></dl></div>

    1. <tfoot id='vZto8'></tfoot>

    2. 在 .NET 5 中测试 Azure 函数

      时间:2023-10-25
      <legend id='lpgvO'><style id='lpgvO'><dir id='lpgvO'><q id='lpgvO'></q></dir></style></legend>

      1. <tfoot id='lpgvO'></tfoot>
          <i id='lpgvO'><tr id='lpgvO'><dt id='lpgvO'><q id='lpgvO'><span id='lpgvO'><b id='lpgvO'><form id='lpgvO'><ins id='lpgvO'></ins><ul id='lpgvO'></ul><sub id='lpgvO'></sub></form><legend id='lpgvO'></legend><bdo id='lpgvO'><pre id='lpgvO'><center id='lpgvO'></center></pre></bdo></b><th id='lpgvO'></th></span></q></dt></tr></i><div id='lpgvO'><tfoot id='lpgvO'></tfoot><dl id='lpgvO'><fieldset id='lpgvO'></fieldset></dl></div>

            • <bdo id='lpgvO'></bdo><ul id='lpgvO'></ul>
                <tbody id='lpgvO'></tbody>
            • <small id='lpgvO'></small><noframes id='lpgvO'>

                本文介绍了在 .NET 5 中测试 Azure 函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着跟版网的小编来一起学习吧!

                问题描述

                我已经开始开发 Azure Functions,现在我想创建我的第一个单元/集成测试,但我完全陷入了困境.虽然我有一个非常简单的函数,带有 HTTP 触发器和 HTTP 和存储队列输出,但测试它似乎非常复杂.

                I've started developing Azure Functions and now I want to create my first unit/integration test, but I'm completely stuck. Although I have a very simple Function with an HTTP Trigger and HTTP and Storage Queue output, it seems ridiculously complex te test this.

                代码(简化):

                public class MyOutput
                {
                    [QueueOutput("my-queue-name", Connection = "my-connection")]
                    public string QueueMessage { get; set; }
                
                    public HttpResponseData HttpResponse { get; set; }
                }
                
                public static class MyFunction
                {
                    [Function(nameof(MyFunction))]
                    public static async Task<MyOutput> Run(
                        [HttpTrigger(AuthorizationLevel.Function, "POST")] HttpRequestData req,
                        FunctionContext executionContext)
                    {
                        var logger = executionContext.GetLogger(nameof(MyFunction));
                        logger.LogInformation("Received {Bytes} bytes", req.Body.Length);
                        //implementation
                    }
                }
                

                现在我希望构建这样的测试:

                Now I'd expect to build a test like this:

                public async Task Test()
                {
                    var response = await MyFunction.Run(..., ...);
                    Assert.IsNotNull(response);
                }
                

                在网上找了几个小时找到一个好方法后,我仍然没有找到模拟 HttpRequestDataFunctionContext 的方法.我还通过设置服务器来寻找完整的集成测试,但这似乎真的很复杂.我最终得到的唯一结果是:https://github.com/Azure/azure-functions-dotnet-worker/blob/72b9d17a485eda1e6e3626a9472948be1152ab7d/test/E2ETests/E2ETests/HttpEndToEndTests.cs

                After looking hours on the internet to find a good approach, I still didn't find a way to mock HttpRequestData and FunctionContext. I also looked for a full integration test by setting up a server, but this seems really complex. The only thing I ended up was this: https://github.com/Azure/azure-functions-dotnet-worker/blob/72b9d17a485eda1e6e3626a9472948be1152ab7d/test/E2ETests/E2ETests/HttpEndToEndTests.cs

                有没有人有在 .NET 5 中测试 Azure Functions 的经验,谁能帮我推动正确的方向?有没有关于如何在 dotnet-isolated 中测试 Azure Function 的好文章或示例?

                Does anyone have experience testing Azure Functions in .NET 5, who can give me a push in the right direction? Are there any good articles or examples on how to test an Azure Function in dotnet-isolated?

                推荐答案

                解决方案一

                我终于可以模拟整个事情了.绝对不是我最好的工作,可以使用一些重构,但至少我得到了一个工作原型:

                Solution 1

                I was finally able to mock the whole thing. Definitely not my best work and can use some refactoring, but at least I got a working prototype:

                var serviceCollection = new ServiceCollection();
                serviceCollection.AddScoped<ILoggerFactory, LoggerFactory>();
                var serviceProvider = serviceCollection.BuildServiceProvider();
                
                var context = new Mock<FunctionContext>();
                context.SetupProperty(c => c.InstanceServices, serviceProvider);
                
                var byteArray = Encoding.ASCII.GetBytes("test");
                var bodyStream = new MemoryStream(byteArray);
                
                var request = new Mock<HttpRequestData>(context.Object);
                request.Setup(r => r.Body).Returns(bodyStream);
                request.Setup(r => r.CreateResponse()).Returns(() =>
                {
                    var response = new Mock<HttpResponseData>(context.Object);
                    response.SetupProperty(r => r.Headers, new HttpHeadersCollection());
                    response.SetupProperty(r => r.StatusCode);
                    response.SetupProperty(r => r.Body, new MemoryStream());
                    return response.Object;
                });
                
                var result = await MyFunction.Run(request.Object, context.Object);
                result.HttpResponse.Body.Seek(0, SeekOrigin.Begin);
                var reader = new StreamReader(result.HttpResponse.Body);
                var responseBody = await reader.ReadToEndAsync();
                
                Assert.IsNotNull(result);
                Assert.AreEqual(HttpStatusCode.OK, result.HttpResponse.StatusCode);
                Assert.AreEqual("Hello test", responseBody);
                

                解决方案 2

                我通过依赖注入添加了 Logger,并为 HttpRequestDataHttpResponseData 创建了我自己的实现.这更容易重复使用,并使测试本身更干净.

                Solution 2

                I added the Logger via Dependency Injection and created my own implementations for HttpRequestData and HttpResponseData. This is way easier to re-use and makes the tests itself cleaner.

                public class FakeHttpRequestData : HttpRequestData
                {
                        public FakeHttpRequestData(FunctionContext functionContext, Uri url, Stream body = null) : base(functionContext)
                    {
                        Url = url;
                        Body = body ?? new MemoryStream();
                    }
                
                    public override Stream Body { get; } = new MemoryStream();
                
                    public override HttpHeadersCollection Headers { get; } = new HttpHeadersCollection();
                
                    public override IReadOnlyCollection<IHttpCookie> Cookies { get; }
                
                    public override Uri Url { get; }
                
                    public override IEnumerable<ClaimsIdentity> Identities { get; }
                
                    public override string Method { get; }
                
                    public override HttpResponseData CreateResponse()
                    {
                        return new FakeHttpResponseData(FunctionContext);
                    }
                }
                
                public class FakeHttpResponseData : HttpResponseData
                {
                    public FakeHttpResponseData(FunctionContext functionContext) : base(functionContext)
                    {
                    }
                
                    public override HttpStatusCode StatusCode { get; set; }
                    public override HttpHeadersCollection Headers { get; set; } = new HttpHeadersCollection();
                    public override Stream Body { get; set; } = new MemoryStream();
                    public override HttpCookies Cookies { get; }
                }
                

                现在测试看起来像这样:

                Now the test looks like this:

                // Arrange
                var body = new MemoryStream(Encoding.ASCII.GetBytes("{ "test": true }"))
                var context = new Mock<FunctionContext>();
                var request = new FakeHttpRequestData(
                                context.Object, 
                                new Uri("https://stackoverflow.com"), 
                                body);
                
                // Act
                var function = new MyFunction(new NullLogger<MyFunction>());
                var result = await function.Run(request);
                result.HttpResponse.Body.Position = 0;
                
                // Assert
                var reader = new StreamReader(result.HttpResponse.Body);
                var responseBody = await reader.ReadToEndAsync();
                Assert.IsNotNull(result);
                Assert.AreEqual(HttpStatusCode.OK, result.HttpResponse.StatusCode);
                Assert.AreEqual("Hello test", responseBody);
                

                这篇关于在 .NET 5 中测试 Azure 函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!

                上一篇:如何使用 Azure Functions 删除 blob? 下一篇:禁用 Azure Functions 的属性在 Visual Studio 2017 中不起作用

                相关文章

              • <legend id='W4gg0'><style id='W4gg0'><dir id='W4gg0'><q id='W4gg0'></q></dir></style></legend>

                    <small id='W4gg0'></small><noframes id='W4gg0'>

                    <tfoot id='W4gg0'></tfoot>
                    <i id='W4gg0'><tr id='W4gg0'><dt id='W4gg0'><q id='W4gg0'><span id='W4gg0'><b id='W4gg0'><form id='W4gg0'><ins id='W4gg0'></ins><ul id='W4gg0'></ul><sub id='W4gg0'></sub></form><legend id='W4gg0'></legend><bdo id='W4gg0'><pre id='W4gg0'><center id='W4gg0'></center></pre></bdo></b><th id='W4gg0'></th></span></q></dt></tr></i><div id='W4gg0'><tfoot id='W4gg0'></tfoot><dl id='W4gg0'><fieldset id='W4gg0'></fieldset></dl></div>
                      <bdo id='W4gg0'></bdo><ul id='W4gg0'></ul>