Quantcast
Channel: かずきのBlog@hatena
Viewing all articles
Browse latest Browse all 1387

Azure Functions v2 の HttpTrigger の関数を単体テストしたいね

$
0
0

端的にいうと HttpRequest クラスやら IActionResult クラスやらを引数や戻り値に持つもののテストです。 ここら辺を Moq を使ってモックしてみたいと思います。テスト対象は、HttpTrigger を使って作成したデフォルトの関数です。以下のような感じ。

using System;
using System.IO;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.AspNetCore.Http;
using Microsoft.Azure.WebJobs.Host;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;

namespace FunctionApp1
{
    publicstaticclass Function1
    {
        [FunctionName("Function1")]
        publicstatic async Task<IActionResult> Run([HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)]HttpRequest req, ILogger log)
        {
            log.LogInformation("C# HTTP trigger function processed a request.");

            string name = req.Query["name"];

            string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
            dynamic data = JsonConvert.DeserializeObject(requestBody);
            name = name ?? data?.name;

            return name != null
                ? (ActionResult)new OkObjectResult($"Hello, {name}")
                : new BadRequestObjectResult("Please pass a name on the query string or in the request body");
        }
    }
}

GET の場合と POST の場合とで処理が分かれてるのと、正しいパラメータが渡ってこなかったときの 3 パターンくらいでしょうか。さくっと xUnit と Moq を導入したプロジェクトで、こんな感じのコードで行けました。

using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using Moq;
using System;
using System.IO;
using System.Text;
using System.Threading.Tasks;
using Xunit;

namespace XUnitTestProject1
{
    publicclass UnitTest1
    {
        [Fact]
        public async Task GetPattern()
        {
            var httpRequestMock = new Mock<HttpRequest>();
            httpRequestMock.Setup(x => x.Query["name"]).Returns("Tanaka");
            httpRequestMock.Setup(x => x.Body).Returns(new MemoryStream());
            var response = await FunctionApp1.Function1.Run(httpRequestMock.Object, new Mock<ILogger>().Object);
            var okObjectResult = Assert.IsType<OkObjectResult>(response);
            Assert.Equal("Hello, Tanaka", okObjectResult.Value asstring);
        }

        [Fact]
        public async Task PostPattern()
        {
            var httpRequestMock = new Mock<HttpRequest>();
            httpRequestMock.Setup(x => x.Query).Returns(new Mock<IQueryCollection>().Object);
            var body = new MemoryStream();
            var json = Encoding.UTF8.GetBytes("{ name: 'Tanaka' }");
            await body.WriteAsync(json, 0, json.Length);
            body.Seek(0, SeekOrigin.Begin);
            httpRequestMock.Setup(x => x.Body).Returns(body);

            var response = await FunctionApp1.Function1.Run(httpRequestMock.Object, new Mock<ILogger>().Object);
            var okObjectResult = Assert.IsType<OkObjectResult>(response);
            Assert.Equal("Hello, Tanaka", okObjectResult.Value asstring);
        }

        [Fact]
        public async Task BadRequestPattern()
        {
            var httpRequestMock = new Mock<HttpRequest>();
            httpRequestMock.Setup(x => x.Query).Returns(new Mock<IQueryCollection>().Object);
            httpRequestMock.Setup(x => x.Body).Returns(new MemoryStream());

            var response = await FunctionApp1.Function1.Run(httpRequestMock.Object, new Mock<ILogger>().Object);
            var badRequestObjectResult = Assert.IsType<BadRequestObjectResult>(response);
            Assert.Equal("Please pass a name on the query string or in the request body", badRequestObjectResult.Value asstring);
        }
    }
}

意外と簡単ですね。Moq は割と強い。


Viewing all articles
Browse latest Browse all 1387

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>