Skip to main content

C# Unit Testing with Top-Level Statements

This example lives in the pulumi/examples repository. Check out just this directory to use it:

Get started with this example
git clone --filter=blob:none --sparse https://github.com/pulumi/examples pulumi-examples
git -C pulumi-examples sparse-checkout set testing-unit-cs-top-level-program
cd pulumi-examples/testing-unit-cs-top-level-program

In this example project, we examine how to unit test C# Pulumi programs that are using top-level statements with dotnet SDK v6. These programs look like this

using Pulumi;
return await Deployment.RunAsync(() =>
{
// Create resources here
});

In order to unit test this piece of code, we have to do a bit of rewriting such that we don’t run the Deployment.RunAsync function because it expects the program is being executed from the Pulumi CLI.

Now, we take the lambda that is provided to Deployment.RunAsync and move it in a place where we can reference it later from our unit test project. The following snippet shows this

using Pulumi;
return await Deployment.RunAsync(Deploy.Infra);
public class Deploy
{
public static Dictionary<string, object?> Infra()
{
// Create resources here
}
}

Here, the code that creates resources and returns outputs is inside the Deploy.Infra function which we can reference from the test project.

The return type of Deploy.Infra could also have been any of the following

  • void when we are not returning any outputs
  • Task when we want to await async code
  • Task<Dictionary<string, object?>> when we want to await async code and return outputs

Now we are ready to write unit tests. From a test project called Tests, add a reference to the project that contains the Pulumi program:

<ItemGroup>
<ProjectReference Include="..\infra\Infra.csproj" />
</ItemGroup>

Now, just for the tests we can create a test stack that uses Deploy.Infra as follows

class TestStack : Stack
{
public TestStack()
{
Outputs = Deploy.Infra();
}
public Dictionary<string, object?> Outputs { get; set; }
}

Then, we can use this test stack to build resources and make assertions about them:

[Test]
public async Task StackExportsWebsiteUrl()
{
var options = new TestOptions { IsPreview = false };
var resources = await Pulumi.Deployment.TestAsync<TestStack>(new Mocks(), options);
var stack = resources.OfType<TestStack>().First();
Assert.That(stack.Outputs.ContainsKey("endpoint"), "Stack should have an endpoint output");
if (stack.Outputs["endpoint"] is Output<string> endpoint)
{
var endpointValue = await endpoint.GetValueAsync();
endpointValue.Should().Be("https://wwwprodsa.web.core.windows.net");
}
}

The rest of the unit testing constructs such as Mocks are covered in the blog post: Unit Testing Cloud Deployments with .NET

Related

The infrastructure as code platform for any cloud.