コンシューマー主導の契約: コンシューマーあたりのスタブ数

同じエンドポイントの 2 人のコンシューマーが 2 つの異なるレスポンスを必要とする場合があります。

このアプローチにより、どのコンシューマーが API のどの部分を使用しているのかをすぐに知ることもできます。API が生成するレスポンスの一部を削除して、自動生成されたテストのどれが失敗したかを確認できます。何も失敗しなかった場合は、レスポンスのその部分は誰も使用しないため、安全に削除できます。

次の、2 つのコンシューマー (foo-consumer および bar-consumer) を持つ producer というプロデューサーに対して定義された契約の例を考えてみましょう。

民生用 foo-service
request {
   url '/foo'
   method GET()
}
response {
    status OK()
    body(
       foo: "foo"
    }
}
民生用 bar-service
request {
   url '/bar'
   method GET()
}
response {
    status OK()
    body(
       bar: "bar"
    }
}

同じリクエストに対して 2 つの異なるレスポンスを生成することはできません。そのため、契約を適切にパッケージ化し、stubsPerConsumer 機能から利益を得ることができます。

プロデューサー側では、コンシューマーは、自分に関連する契約のみを含むフォルダーを持つことができます。stubrunner.stubs-per-consumer フラグを true に設定すると、すべてのスタブが登録されるのではなく、コンシューマーアプリケーションの名前に対応するスタブのみが登録されるようになります。つまり、すべてのスタブのパスをスキャンし、そのパスにコンシューマーの名前を持つサブフォルダーが含まれている場合にのみ、そのサブフォルダーが登録されます。

foo プロデューサー側の契約は次のようになります

.
└── contracts
    ├── bar-consumer
    │   ├── bookReturnedForBar.groovy
    │   └── shouldCallBar.groovy
    └── foo-consumer
        ├── bookReturnedForFoo.groovy
        └── shouldCallFoo.groovy

bar-consumer コンシューマーは、spring.application.name または stubrunner.consumer-name を bar-consumer に設定できます。あるいは、次のようにテストを設定することもできます。

@SpringBootTest(classes = Config, properties = ["spring.application.name=bar-consumer",
		"stubrunner.jms.enabled=false"])
@AutoConfigureStubRunner(ids = "org.springframework.cloud.contract.verifier.stubs:producerWithMultipleConsumers",
		repositoryRoot = "classpath:m2repo/repository/",
		stubsMode = StubRunnerProperties.StubsMode.REMOTE,
		stubsPerConsumer = true)
@ActiveProfiles("streamconsumer")
class StubRunnerStubsPerConsumerSpec {
...
}

これにより、名前に bar-consumer が含まれるパスに登録されたスタブ (つまり、src/test/resources/contracts/bar-consumer/some/contracts/…​ フォルダーのスタブ) のみが参照できるようになります。

次のように、コンシューマー名を明示的に設定することもできます。

@SpringBootTest(classes = Config, properties = "stubrunner.jms.enabled=false")
@AutoConfigureStubRunner(ids = "org.springframework.cloud.contract.verifier.stubs:producerWithMultipleConsumers",
        repositoryRoot = "classpath:m2repo/repository/",
        consumerName = "foo-consumer",
        stubsMode = StubRunnerProperties.StubsMode.REMOTE,
        stubsPerConsumer = true)
@ActiveProfiles("streamconsumer")
class StubRunnerStubsPerConsumerWithConsumerNameSpec {
...
}

これにより、名前に foo-consumer が含まれるパスに登録されたスタブ (つまり、src/test/resources/contracts/foo-consumer/some/contracts/…​ フォルダーのスタブ) のみが参照できるようになります。

この変更の背後にある理由の詳細については、第 224 号 [GitHub] (英語) を参照してください。