c# - 単体テスト - xunit nunit mstest 比較




ネットコア:AppService、リポジトリなどのXunitテストですべての依存性注入を実行します (2)

テストするとき。 モックライブラリを使用するか、contructorにサービスを直接注入する必要があります。

public DBContext context;
public IDepartmentAppService departmentAppService;

/// Inject DepartmentAppService here
public DepartmentAppServiceTest(DepartmentAppService departmentAppService)
{
    this.departmentAppService = departmentAppService;
}

AppServiceのXunitテストで依存性注入を実装しようとしています。 理想的な目標は、元のアプリケーションプログラムのスタートアップ/構成を実行し、テストですべてのDIを再初期化するのではなく、スタートアップにあった依存関係の注入を使用することです。

更新:Mohsenの答えは近い。 動作するために、いくつかの構文/要件エラーを更新する必要があります。

何らかの理由で、元のアプリケーションが機能し、Department App Serviceを呼び出すことができます。 ただし、Xunitで呼び出すことはできません。 最終的に、元のアプリケーションのスタートアップと構成を使用してTestserverが動作するようになりました。 以下のエラーが表示されます:

Message: The following constructor parameters did not have matching fixture data: IDepartmentAppService departmentAppService

namespace Testing.IntegrationTests
{
    public class DepartmentAppServiceTest
    {
        public DBContext context;
        public IDepartmentAppService departmentAppService;

        public DepartmentAppServiceTest(IDepartmentAppService departmentAppService)
        {
            this.departmentAppService = departmentAppService;
        }

        [Fact]
        public async Task Get_DepartmentById_Are_Equal()
        {
            var options = new DbContextOptionsBuilder<SharedServicesContext>()
                .UseInMemoryDatabase(databaseName: "TestDatabase")
                .Options;
            context = new DBContext(options);

            TestServer _server = new TestServer(new WebHostBuilder()
                .UseContentRoot("C:\\OriginalApplication")
                .UseEnvironment("Development")
                .UseConfiguration(new ConfigurationBuilder()
                    .SetBasePath("C:\\OriginalApplication")
                    .AddJsonFile("appsettings.json")
                    .Build()).UseStartup<Startup>());

            context.Department.Add(new Department { DepartmentId = 2, DepartmentCode = "123", DepartmentName = "ABC" });
            context.SaveChanges();

            var departmentDto = await departmentAppService.GetDepartmentById(2);

            Assert.Equal("123", departmentDto.DepartmentCode);
        }
    }
}

私はこのエラーを受け取っています:

Message: The following constructor parameters did not have matching fixture data: IDepartmentAppService departmentAppService

テストでは、実際のアプリケーションと同じように依存性注入を使用する必要があります。 元のアプリケーションがこれを行います。 以下の回答は現在十分ではありません。1つは現在の目標ではないモックを使用し、他の回答は質問の目的をバイパスするコントローラーを使用します。

注:IDepartmentAppServiceは、Startupクラスにも挿入されるIDepartmentRepositoryおよびAutomapper依存関係に依存しています。 これが、スタートアップクラス全体を呼び出す理由です。

良いリソース:

コンストラクター依存性注入を使用したasp.netコアアプリケーションの単体テスト方法

Xunitプロジェクトでの依存性注入


以下のカスタムWebアプリケーションファクトリとServiceProvider.GetRequiredServiceを使用して、回答を自由に編集および最適化してください

CustomWebApplicationFactory:

public class CustomWebApplicationFactory<TStartup> : WebApplicationFactory<TStartup> where TStartup : class
{
    protected override void ConfigureWebHost(IWebHostBuilder builder)
    {
        builder.ConfigureAppConfiguration((hostingContext, configurationBuilder) =>
        {
            var type = typeof(TStartup);
            var path = @"C:\\OriginalApplication";

            configurationBuilder.AddJsonFile($"{path}\\appsettings.json", optional: true, reloadOnChange: true);
            configurationBuilder.AddEnvironmentVariables();
        });

        // if you want to override Physical database with in-memory database
        builder.ConfigureServices(services =>
        {
            var serviceProvider = new ServiceCollection()
                .AddEntityFrameworkInMemoryDatabase()
                .BuildServiceProvider();

            services.AddDbContext<ApplicationDBContext>(options =>
            {
                options.UseInMemoryDatabase("DBInMemoryTest");
                options.UseInternalServiceProvider(serviceProvider);
            });
        });
    }
}

統合テスト:

public class DepartmentAppServiceTest : IClassFixture<CustomWebApplicationFactory<OriginalApplication.Startup>>
{
    public CustomWebApplicationFactory<OriginalApplication.Startup> _factory;
    public DepartmentAppServiceTest(CustomWebApplicationFactory<OriginalApplication.Startup> factory)
    {
        _factory = factory;
        _factory.CreateClient();
    }

    [Fact]
    public async Task ValidateDepartmentAppService()
    {      
        using (var scope = _factory.Server.Host.Services.CreateScope())
        {
            var departmentAppService = scope.ServiceProvider.GetRequiredService<IDepartmentAppService>();
            var dbtest = scope.ServiceProvider.GetRequiredService<ApplicationDBContext>();
            dbtest.Department.Add(new Department { DepartmentId = 2, DepartmentCode = "123", DepartmentName = "ABC" });
            dbtest.SaveChanges();
            var departmentDto = await departmentAppService.GetDepartmentById(2);
            Assert.Equal("123", departmentDto.DepartmentCode);
        }
    }
}

リソース:

https://docs.microsoft.com/en-us/aspnet/core/test/integration-tests?view=aspnetcore-2.2

https://fullstackmark.com/post/20/painless-integration-testing-with-aspnet-core-web-api







xunit