😀

.NET 6 の Azure Functions で xUnit を使ってみた

に公開

.NET の Azure Functions でバックエンドアプリケーションを開発しています。公式ドキュメント通りに進めると、dotnet コマンドは使わず、func コマンドで開発を進めることになります。とはいえ、func コマンドの裏ではおそらく dotnet build しているだろうから、dotnet test もできるはず。ということで、xUnit を使ってユニットテスト(単体テスト)をやってみました。

Azure Functions と xUnit プロジェクトをまとめる .NET ソリューションを作成

bash
dotnet new sln -o sampleapp

cd sampleapp

Azure Functions プロジェクトを作成

bash
func init sampleapp --dotnet

cd sampleapp

func new --name Sample --template HttpTrigger

func start

.NET ソリューションに Azure Functions プロジェクトを

bash
cd ..

dotnet sln add sampleapp/sampleapp.csproj

dotnet build

xUnit プロジェクトを作成

bash
dotnet new xunit -o sampleapp.tests

dotnet add sampleapp.tests/sampleapp.tests.csproj \
  reference sampleapp/sampleapp.csproj

dotnet sln add sampleapp.tests/sampleapp.tests.csproj

dotnet test
VSTest のバージョン 17.11.1 (arm64)

テスト実行を開始しています。お待ちください...
合計 1 個のテスト ファイルが指定されたパターンと一致しました。

成功!   -失敗:     0、合格:     1、スキップ:     0、合計:     1、期間: < 1 ms - sampleapp.tests.dll (net8.0)

テストコードを変更

bash
cd sampleapp.tests

dotnet add package Moq

code UnitTest1.cs
UnitTest1.cs
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using Xunit;
using Moq;

namespace sampleapp.tests;

public class UnitTest1
{
    [Fact]
    public async Task Run_ReturnsOkResult_WhenNameIsNonProvided()
    {
        var mockLogger = new Mock<ILogger>();
        var httpContext = new DefaultHttpContext();
        httpContext.Request.QueryString = new QueryString();
        var request = httpContext.Request;
        var result = await sampleapp.Sample.Run(request, mockLogger.Object);

        var okResult = Assert.IsType<OkObjectResult>(result);
        Assert.Equal("This HTTP triggered function executed successfully. Pass a name in the query string or in the request body for a personalized response.", okResult.Value);
    }

    [Fact]
    public async Task Run_ReturnsOkResult_WhenNameIsProvided()
    {
        var mockLogger = new Mock<ILogger>();
        var httpContext = new DefaultHttpContext();
        httpContext.Request.QueryString = new QueryString("?name=John");
        var request = httpContext.Request;
        var result = await sampleapp.Sample.Run(request, mockLogger.Object);

        var okResult = Assert.IsType<OkObjectResult>(result);
        Assert.Equal("Hello, John. This HTTP triggered function executed successfully.", okResult.Value);
    }
}

ユニットテスト実行

bash
dotnet test
VSTest のバージョン 17.11.1 (arm64)

テスト実行を開始しています。お待ちください...
合計 1 個のテスト ファイルが指定されたパターンと一致しました。

成功!   -失敗:     0、合格:     2、スキップ:     0、合計:     2、期間: 2 ms - sampleapp.tests.dll (net8.0)
bash
cd ..

dotnet test
VSTest のバージョン 17.11.1 (arm64)

テスト実行を開始しています。お待ちください...
合計 1 個のテスト ファイルが指定されたパターンと一致しました。

成功!   -失敗:     0、合格:     2、スキップ:     0、合計:     2、期間: 1 ms - sampleapp.tests.dll (net8.0)

参考

https://learn.microsoft.com/ja-jp/dotnet/core/testing/unit-testing-with-dotnet-test

https://learn.microsoft.com/ja-jp/azure/devops/pipelines/ecosystems/dotnet-core?view=azure-devops&tabs=yaml-editor

https://learn.microsoft.com/ja-jp/dotnet/core/testing/unit-testing-best-practices

Discussion