端的にいうと 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 は割と強い。