ABP IntegratedTest
ABP IntegratedTest
2023/6/1
➡️

abp IntegratedTest

abp testBase 为 abp 项目测试提供的测试工具,只能测试单独的模块,不能和 asp.net core 一起测 试

AbpTestBaseWithServiceProvider 抽象类定义功能

public abstract class AbpTestBaseWithServiceProvider
{
    protected IServiceProvider ServiceProvider { get; set; } = default!;

    protected virtual T? GetService<T>()
    {
        return ServiceProvider.GetService<T>();
    }

    protected virtual T GetRequiredService<T>() where T : notnull
    {
        return ServiceProvider.GetRequiredService<T>();
    }
}

AbpTestBaseWithServiceProvider 的异步实现, AbpIntegratedTest 类似

public class AbpAsyncIntegratedTest<TStartupModule> : AbpTestBaseWithServiceProvider
    where TStartupModule : IAbpModule
{
    protected IAbpApplication Application { get; set; } = default!;

    protected IServiceProvider RootServiceProvider { get; set; } = default!;

    protected IServiceScope TestServiceScope { get; set; } = default!;

    public virtual async Task InitializeAsync()
    {
        var services = await CreateServiceCollectionAsync();

        await BeforeAddApplicationAsync(services);

        //生成应用程序,使用abp 的模块化
        var application = await services.AddApplicationAsync<TStartupModule>(
          await SetAbpApplicationCreationOptionsAsync());

        await AfterAddApplicationAsync(services);

        //获取 IServiceProvider
        RootServiceProvider = await CreateServiceProviderAsync(services);
        // 生成局部 Scope
        TestServiceScope = RootServiceProvider.CreateScope();

        // 初始化应用程序 TestServiceScope.ServiceProvider 保证了使用的服务都是在
        // TestServiceScope 范围内
        await application.InitializeAsync(TestServiceScope.ServiceProvider);

        ServiceProvider = application.ServiceProvider;
        Application = application;

        await InitializeServicesAsync();
    }



    public virtual async Task DisposeAsync()
    {
        await Application.ShutdownAsync();
        TestServiceScope.Dispose();
        Application.Dispose();
    }

    protected virtual Task<IServiceCollection> CreateServiceCollectionAsync()
    {
        return Task.FromResult<IServiceCollection>(new ServiceCollection());
    }

    protected virtual Task BeforeAddApplicationAsync(IServiceCollection services)
    {
        return Task.CompletedTask;
    }

    protected virtual Task<Action<AbpApplicationCreationOptions>>
     SetAbpApplicationCreationOptionsAsync()
    {
        return Task.FromResult<Action<AbpApplicationCreationOptions>>(_ => { });
    }

    protected virtual Task AfterAddApplicationAsync(IServiceCollection services)
    {
        return Task.CompletedTask;
    }

    protected virtual Task<IServiceProvider> CreateServiceProviderAsync(
      IServiceCollection services)
    {
        return Task.FromResult(services.BuildServiceProviderFromFactory());
    }

    protected virtual Task InitializeServicesAsync()
    {
        return Task.CompletedTask;
    }
}

Volo.Abp.AspNetCore.TestBase

可以和 asp.net core 一起测试,需要使用 Microsoft.AspNetCore.Mvc.Testing 进行集成测试

主要的实现是 AbpWebApplicationFactoryIntegratedTest

参考微软官方文件一样 https://learn.microsoft.com/zh-cn/aspnet/core/fundamentals/minimal-apis/test-min-api?view=aspnetcore-7.0

namespace Volo.Abp.AspNetCore.TestBase;

//TProgram 在 asp.net 6 以上因为顶级语句的原有需要自己写个分布类 Programer
public abstract class AbpWebApplicationFactoryIntegratedTest<TProgram>
: WebApplicationFactory<TProgram>
    where TProgram : class
{
    protected HttpClient Client { get; set; }

    protected IServiceProvider ServiceProvider => Services;

    protected AbpWebApplicationFactoryIntegratedTest()
    {
        //用于测试 web api 的client
        Client = CreateClient(new WebApplicationFactoryClientOptions
        {
            AllowAutoRedirect = false
        });
        ServiceProvider.GetRequiredService<ITestServerAccessor>().Server = Server;
    }


    //在这个过程是可以修改内存服务器的配置及服务在这里
    protected override IHost CreateHost(IHostBuilder builder)
    {
        builder
            .AddAppSettingsSecretsJson()
            .ConfigureServices(ConfigureServices);
        return base.CreateHost(builder);
    }

    protected virtual T? GetService<T>()
    {
        return Services.GetService<T>();
    }

    protected virtual T GetRequiredService<T>() where T : notnull
    {
        return Services.GetRequiredService<T>();
    }

    protected virtual void ConfigureServices(IServiceCollection services)
    {

    }
    protected virtual string GetUrl<TController>()
    {
        return "/" + typeof(TController).Name.RemovePostFix("Controller",
        "AppService", "ApplicationService", "IntService", "IntegrationService", "Service");
    }
    protected virtual string GetUrl<TController>(string actionName)
    {
        return GetUrl<TController>() + "/" + actionName;
    }
    protected virtual string GetUrl<TController>(string actionName,
     object queryStringParamsAsAnonymousObject)
    {
        var url = GetUrl<TController>(actionName);

        var dictionary = new RouteValueDictionary(queryStringParamsAsAnonymousObject);
        if (dictionary.Any())
        {
            url += "?" + dictionary.Select(d => $"{d.Key}={d.Value}").JoinAsString("&");
        }
        return url;
    }
}
👍🎉🎊