.NET xUnit で統合テストの作成
2023年 02月 07日 火曜日
手順
基本は公式サイト(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();
この記事をシェア