.NET xUnit で統合テストの作成

手順

基本は公式サイト(Integration tests in ASP.NET Core)に沿いながら、作成していきます。

Program.cs に以下のコードを一番下に追加します。

public partial class Program { }

TestingWebAppFactory.cs

  • カスタマイズの WebApplicationFactory
    • Github Action だと、Ubuntu になるので、ConnectionString にパスワードを設定しなけらばならない
    • 各テストで EntityFrameworkCore を使いたいので、context を public にする(ちゃんと dispose するかどうか怪しいので、もっといい方法があるでしょ)
    • context.Database.EnsureDeleted(); context.Database.EnsureCreated(); により、テストを実行するたびに、DB が再生成される
...
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc.Testing;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;

namespace xxx.Tests;

public class TestingWebAppFactory<TEntryPoint> : WebApplicationFactory<Program> where TEntryPoint : Program
{
    public DataContext context { get; private set; } = null!;
    protected override void ConfigureWebHost(IWebHostBuilder builder)
    {
        builder.ConfigureServices(services =>
        {
            var descriptor = services.SingleOrDefault(
                d => d.ServiceType ==
                    typeof(DbContextOptions<DataContext>));

            if (descriptor != null)
                services.Remove(descriptor);

            services.AddDbContext<DataContext>(options =>
            {
                options
                    .UseNpgsql("Server=localhost;Port=5432;Database=xxxx_test;Username=postgres;Password=postgres;Integrated Security=true;Pooling=true;")
                    .UseSnakeCaseNamingConvention();
            });

            var sp = services.BuildServiceProvider();
            var scope = sp.CreateScope();
            context = scope.ServiceProvider.GetRequiredService<Dataontext>();

            try
            {
                context.Database.EnsureDeleted();
                context.Database.EnsureCreated();
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex);
                throw;
            }
        });
    }
}

ModelControllerTest.cs

  • JSON 形で API にパラメータを渡し、その結果を JSON 形で貰って、テストすることができる
  • BaseAddress を指定しないと、「Failed to determine the https port for redirect」という警告が出る
...
using Microsoft.EntityFrameworkCore;
using Microsoft.AspNetCore.Mvc.Testing;
using Xunit;

[Collection("Controller Test")]
public class ModelControllerTest : IClassFixture<TestingWebAppFactory<Program>>
{
    private readonly HttpClient _client;
    private readonly DataContext _context;
    public ModelControllerTest(TestingWebAppFactory<Program> factory)
    {
        _client = factory.CreateClient(new WebApplicationFactoryClientOptions
        {
            AllowAutoRedirect = false,
            BaseAddress = new System.Uri("https://localhost")
        });
        _context = factory.context;
    }

		[Fact]
		public async Task Test()
		{
			var response = await _client.GetAsync("/api/xxx");
			var postRequest = new HttpRequestMessage(HttpMethod.Post, "/api/xxx")
      {
           Content = JsonContent.Create(params)
      };
      var response = await _client.SendAsync(postRequest);
		}
}
  • Put の場合はリクエストした結果を await リロードしないと数値が変わらない

    await _context.Entry("modelName").ReloadAsync();
この記事をシェア

弊社では、一緒に会社を面白くしてくれる仲間を募集しています。
お気軽にお問い合わせください!