You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
<p>Welcome back to our integration testing in .NET series! In this chapter, we’re diving into the exciting world of testing AWS components integrated into our .NET APIs. For a quick introduction on integration testing, refer to the article below.</p>
15
+
16
+
<BlogReferenceCardTitle="Integration testing for dotnet core APIs: Introduction"
17
+
Description="Integration testing for dotnet core APIs: Introduction"
<p>AWS services (or any cloud services) have become the backbone of modern application development, offering scalable and reliable solutions for a variety of needs. For example, Amazon SNS (Simple Notification Service) sends notifications to users or systems via email, SMS, or other channels. Meanwhile, Amazon SQS (Simple Queue Service) enables asynchronous communication between distributed system components.</p>
23
+
24
+
<h6>Challenges in testing cloud integrations</h6>
25
+
<p>Here’s the twist: while using AWS services like SNS, SQS, S3, or SES is straightforward with the SDK, how do we ensure that our messages actually reach AWS? It’s not just about calling the right method with the right input; it’s about verifying that AWS receives and processes our requests correctly.</p>
26
+
27
+
<h6>Lets dive into the article</h6>
28
+
<p>To make this more fun, imagine we’ve built an API called <code>call-superhero</code>. This API takes a superhero’s name as a parameter and sends an SNS notification, hoping that the superhero hears the call and springs into action!</p>
29
+
30
+
<CodeSnippetNumber="1"Description="Call superhero API to send message to SNS">
31
+
[HttpPost("call-superhero")]
32
+
public async Task<IActionResult> CallSuperHero(string superHeroName)
if (response.HttpStatusCode!=System.Net.HttpStatusCode.OK)
50
+
{
51
+
returnStatusCode((int)response.HttpStatusCode, "Failed to send SNS notification.");
52
+
}
53
+
54
+
returnOk($"Calling {hero.SuperName}! They are on their way to save the day!");
55
+
}
56
+
</CodeSnippet>
57
+
58
+
<p>In the above code, we’re using the SNS client to publish a message to the SNS topic. This ensures that our superhero call is broadcasted loud and clear!</p>
59
+
<p>Here’s a quick recap of the AWS setup we did to make this work:</p>
60
+
<ul>
61
+
<li>Defined appsettings for AWS, including the region and the SNS topic ARN.</li>
62
+
<li>Set up credentials for the application. Check out the <ahref="https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-files.html"target="_blank">official AWS documentation</a> for configuring access key ID and secret access key on your local machine.</li>
63
+
<li>Registered the dependency for <code>IAmazonSimpleNotificationService</code>.</li>
64
+
</ul>
65
+
66
+
<h5>🔧 Configuring appsettings.json</h5>
67
+
<p>Ensure your <code>appsettings.json</code> file includes the following configuration for AWS:</p>
<p><i>Note: To retrieve the SNS Topic ARN, create a topic in the AWS Management Console or using the AWS CLI. Refer to the <ahref="https://docs.aws.amazon.com/sns/latest/dg/sns-create-topic.html"target="_blank">AWS documentation</a> for details.</i></p>
77
+
78
+
<h4>Setting Up LocalStack for Integration Testing</h4>
79
+
<p>LocalStack is like having your own personal AWS cloud running locally. Below is a step-by-step guide to setting it up for integration testing in a .NET application. For more details, refer to the <ahref="https://testcontainers.com/modules/localstack/"target="_blank">Testcontainers.LocalStack documentation</a>.</p>
80
+
81
+
<h5>Define the LocalStack Container</h5>
82
+
<p>The <code>LocalStackContainer</code> is configured using the <code>Testcontainers.LocalStack</code> library. This setup specifies the Docker image, wait strategy, and cleanup options.</p>
<p>We create an SNS topic using the <code>awslocal sns create-topic</code> command inside the LocalStack container. The output is parsed to extract the <code>TopicArn</code>.</p>
public LocalStackContainer LocalStackContainer => _localStackContainer;
128
+
</CodeSnippet>
129
+
130
+
<h5>Clean Up Resources</h5>
131
+
<p>Once the tests are done, the container is stopped and cleaned up to ensure no leftover resources.</p>
132
+
133
+
<CodeSnippetNumber="7"Description="Cleaning up LocalStack container">
134
+
public async Task DisposeAsync()
135
+
{
136
+
await_localStackContainer.DisposeAsync();
137
+
}
138
+
</CodeSnippet>
139
+
140
+
<p>With this setup, LocalStack is ready to emulate AWS services for integration testing. By using <code>LocalStackContainer.ExecAsync</code>, you can directly execute AWS CLI commands inside the LocalStack container, making it easy to manage AWS resources like SNS topics and SQS queues during tests.</p>
141
+
142
+
<h4>LocalStack Setup in CustomApiFactory</h4>
143
+
<p>The <code>CustomApiFactory</code> class is responsible for configuring the test environment, including setting up LocalStack for integration testing. Below are the steps and code snippets related to LocalStack setup in this class.</p>
144
+
145
+
<h5>Replace the SNS Client with LocalStack</h5>
146
+
<p>The existing <code>IAmazonSimpleNotificationService</code> client is replaced with a LocalStack SNS client. This ensures that all SNS operations during tests are directed to LocalStack.</p>
147
+
148
+
<CodeSnippetNumber="8"Description="Null check for snsClient">
<p>The <code>GetSnsClient</code> method creates an SNS client configured to use the LocalStack endpoint. This client is used for all SNS operations during tests.</p>
161
+
162
+
<CodeSnippetNumber="9"Description="Method to create LocalStack SNS client">
<p>The SNS topic ARN created in LocalStack is injected into the application configuration. This ensures that the application uses the correct topic ARN during tests.</p>
<p>The <code>CustomApiFactory</code> class ensures that all SNS operations during integration tests are directed to LocalStack. By replacing the default SNS client and overriding the application configuration, it provides a seamless testing environment for AWS integrations.</p>
190
+
191
+
<h4>Finally, the Test!</h4>
192
+
<p>The test verifies that the <code>CallSuperHero</code> API correctly publishes a message to an SNS topic and that the message is received by an SQS queue subscribed to the topic. This test uses LocalStack to emulate AWS services.</p>
193
+
194
+
<CodeSnippetNumber="11"Description="Test for CallSuperHero API">
195
+
[Fact(DisplayName = "CallSuperHero API raises correct SNS notification using LocalStack")]
196
+
public async Task CallSuperHero_Raises_Correct_SNS_Notification_Using_LocalStack()
<p>This test demonstrates how to use LocalStack to verify that the <code>CallSuperHero</code> API correctly interacts with AWS SNS and SQS. By emulating AWS services locally or via test containers, the test ensures that the API behaves as expected without incurring costs or requiring access to real AWS resources.</p>
242
+
243
+
<p>If you want to explore the actual code discussed in this article, feel free to visit the GitHub repository: <ahref="https://github.com/ajaysskumar/SuperHeroSolution"target="_blank">https://github.com/ajaysskumar/SuperHeroSolution</a>. It contains the complete implementation and test setup for the <code>CallSuperHero</code> API and AWS integration testing using LocalStack.</p>
0 commit comments