C# Unit Testing with Top-Level Statements
This example lives in the pulumi/examples repository. Check out just this directory to use it:
git clone --filter=blob:none --sparse https://github.com/pulumi/examples pulumi-examplesgit -C pulumi-examples sparse-checkout set testing-unit-cs-top-level-programcd pulumi-examples/testing-unit-cs-top-level-programIn 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.Infracould also have been any of the following
voidwhen we are not returning any outputsTaskwhen we want toawaitasync codeTask<Dictionary<string, object?>>when we want toawaitasync 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