1

マイクロサービス環境では、契約ベースのテスト用のフレームワークを構築する必要があります。私は現在、プロバイダー テストを実行するために、単一のサービスを外部依存関係から分離する方法を調査しています。

私がする必要があるのは:

  • WebApi プロジェクトをそのまま維持する
  • いくつかの構成の違いを使用して WepApi のインスタンスを開始します
  • 選択した依存関係をモックアウトする

私のソリューション構造はこれです:

Case-Solution/  
├── src/  
|   ├──Case.Api  
|   └──Case.Application  
├── test/  
|   ├──Case.Api.Unittest  
|   ├──(other tests)  
|   ├──Case.Pact.CunsumerTest  
|   └──Case.Pact.ProviderTest  

dotnet での Pact テストに関するこのガイドを読みました。に焦点を当てると、プログラムで(および Pact 自体の別の WebHost)からCase.Pace.ProviderTest開始し、その依存関係の一部を置き換える必要があります。Case.ApiCase.Pact.ProviderTest

これまでのところ、私はこれを得ました:

public class ProviderApiTests : IDisposable
{
    private string ProviderUri { get; }
    private string PactServiceUri { get; }
    private IWebHost PactServiceWebHost { get; }
    private IWebHost CasesWebHost { get; }
    private ITestOutputHelper OutputHelper { get; }
    public static IConfiguration CaseConfiguration { get; } = new ConfigurationBuilder()
        .SetBasePath(Directory.GetCurrentDirectory())
        .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
        .AddJsonFile($"appsettings.{Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT" ?? "Production"}.json", optional: true)
        .AddEnvironmentVariables()
        .Build();


    public ProviderApiTests(ITestOutputHelper output)
    {
        OutputHelper = output;
        ProviderUri = "http://localhost:9000";
        PactServiceUri = "http://localhost:9001";

        CasesWebHost = WebHost.CreateDefaultBuilder()
            .UseUrls(ProviderUri)
            .UseStartup<CaseStartup>()
            .UseConfiguration(CaseConfiguration)
            .Build();
        CasesWebHost.Start();

        PactServiceWebHost = WebHost.CreateDefaultBuilder()
            .UseUrls(PactServiceUri)
            .UseStartup<ProviderServerStartup>()
            .Build();
        PactServiceWebHost.Start();
    }

    [Fact]
    public void EnsureProviderApiHonoursPactWithConsumer()
    {
        //Arrange
        var config = new PactVerifierConfig
        {
            Outputters = new List<IOutput>
            {
                new XUnitOutput(OutputHelper)
            },
            Verbose = true,
            CustomHeader = new KeyValuePair<string, string>("X-apikey", "XXX")
        };
        //Act //Assert
        IPactVerifier pactVerifier = new PactVerifier(config);
        pactVerifier.ProviderState($"{PactServiceUri}/provider-states")
            .ServiceProvider("CaseProvider", ProviderUri)
            .HonoursPactWith("CaseConsumer")
            .PactUri(@"..\..\..\..\..\pacts\caseconsumer-caseprovider.json")
            .Verify();
    }
    #region IDisposable Support
    //IDisposable code
    #endregion
}

を含む行では、必要な依存関係を.UseStartup<CaseStartup>()単純にコピーStartup.csして変更しましたが、これは正常に機能します。Case.Api

しかし、より一般的なソリューションが必要です。コードをコピーして 1 日で終了するのは適切ではありません :) これは、他のサービスで一般的ではなく、再利用可能ではないためです。

それで私は掘り続け、次のことを思いつきました。

別のアセンブリ
から StartUp を使用して IWebhost を開始しても、そのアセンブリからコントローラーが自動的に追加されないことに気付きました。これは明示的に行う必要があります。だから私はこれをしました:

public void ConfigureServices(IServiceCollection services)
{
    var assembly = Assembly.Load("Case.Api");
    services.AddMvc()
       .SetCompatibilityVersion(CompatibilityVersion.Version_2_1)
       .AddApplicationPart(assembly)
       .AddControllersAsServices();
    ......
}

素晴らしい!!!ここまでは順調ですね。

次号:

依存関係を置き換える:この
記事を 読み直して、依存関係を置き換えるための拡張メソッドを作成しました。

public static void Replace<TRegisteredType>(this IServiceCollection services, TRegisteredType replcement)
{
    for (var i = 0; i < services.Count; i++)
    {
        if (services[i].ServiceType == typeof(TRegisteredType))
        {
            services[i] = new ServiceDescriptor(typeof(TRegisteredType), replcement);
        }
    }
}

したがって、必要な依存関係を次のように置き換えることができます: (この場合は QueryHandler)

public void ConfigureServices(IServiceCollection services)
{
    .....
    var queryHandler = Substitute.For<IQueryHandler<Query, QueryResult>>();
    queryHandler.Handle(Arg.Any<Query>()).Returns(new QueryResult(...));
    services.Replace(queryHandler);
    ......
}

しかし、これはコピーされたコードに関する私の問題を解決しません。

私の甘い夢は、すべての冗長なコードを持たずに、依存関係を置き換えるためにfrom を使用Startup.csし、何らかの方法で DI を微調整できるようにすることです。Case.Api

どんな入力も非常に高く評価されます。
ありがとう :)

4

1 に答える 1