Skip to content

Fake Clients

With SmithyGenerateFakes enabled, codegen emits a Fake{Service}Client implementing I{Service}Client. Code that depends on the client interface runs against it with no server and no network:

<PropertyGroup>
<SmithyGenerateFakes>true</SmithyGenerateFakes>
</PropertyGroup>
IWeatherClient client = new FakeWeatherClient();
var city = await client.GetCityAsync(new GetCityInput(CityId: "zrh"));

With the service container, register it in place of the real client:

services.AddSingleton<IWeatherClient, FakeWeatherClient>();

Responses come from the same synthesis as fake handlers: with several @examples entries the input is matched against the example inputs and the first match decides the response, with a matched error example throwing the modeled error; otherwise the output of the first non-error @examples entry when present, deterministic placeholders everywhere else. The fake client is generated with the client surface (SmithyGenerateClient, on by default). Projects with an explicit smithy-build.json set "generateFakes": true on the csharp-codegen plugin instead.

  • No serialization, protocol, or validation is involved. Every call returns its canned response (or throws its matched error example), including calls a real client or server would reject.
  • Paginators yield a single page. The canned output’s continuation token may be non-null, and following it would never terminate.
  • Every operation responds, including event-stream operations the real client rejects when no declared protocol supports them.

The fake’s operation methods are virtual. In a test, override the operations whose data the test asserts on; everything else keeps its canned response:

internal sealed class TwoCitiesWeatherClient : FakeWeatherClient
{
public override Task<ListCitiesOutput> ListCitiesAsync(
ListCitiesInput input,
CancellationToken cancellationToken = default
) =>
Task.FromResult(
new ListCitiesOutput(
Items: new CitySummaries(
[
new CitySummary(CityId: "SEA", Name: "Seattle"),
new CitySummary(CityId: "HOU", Name: "Houston"),
]
)
)
);
}

Paginators call the virtual unary method, so overriding it also changes the page the paginators yield.