Writing Integration Tests for Azure Event Grid

Azure Event Grid is a serverless pub/sub engine for building event-based architectures, but how do you test your applications? Let's have a look.

Tom Kerkhove

9 August 2018

Building applications is always an adventure and one of the most important aspects is testing. This is no different when building event-driven platforms which use components such as Azure Event Grid.

While there are a lot of different test strategies, we will focus on integration testing today. If you want to learn more about testing I recommend reading The Practical Test Pyramidif you are interested.

I’m a strong believer in integration testing, certainly when you are working in the cloud space. They allow you to test that one component of your application and see if they can integrate, hence the name, with one of your dependencies.

When working with Azure Event Grid this is no different – When you send events to Azure Event Grid, how do you know if the process on the other end can successfully deserialize your message and consume it?

It’s simple – You don’t unless you test it.

This is exactly what we had to do while for Arcuswhich makes Azure Event Grid development easier. There I had to find a way so that I can verify that everything was still working and this article explains how we’ve approached it and how we can help you.

What are we trying to test?

Conceptually Azure Event Grid is a serverless event-driven pub/sub offering which allows parties to emit events to a custom topic and others can create a subscription to start receiving those events by providing a webhook endpoint. (more info)

This is where the problem lies – A webhook endpoint to which all our events will be sent. In a real-world scenario, this will be your deployed application which integrates with Azure Event Grid but in our integration tests we cannot do that as they will be running on my laptop, a CI build, etc.

This means that we need to provide a mechanism which is subscribing to our custom topic and relays all events to our tests.

While tools like ngrokallow you to do that they do not fit our needs because:

They run as a separate process outside of your tests

They need to be installed on every machine running your tests

The good news is – Azure Relay is precisely what we need.

Enter Azure Relay Hybrid Connections

Azure Relay was initially designed by Clemens Vasters which was running on a machine running under a desk at Microsoft and is now grown to a first-class Azure service providing a ton of hybrid integration scenarios in a secure manner.

The service allows you to expose a public endpoint in your application without having to open up any ports on your side. Clients can simply communicate with Azure Relay which will relay, hence the name, all requests to your application.

Once you understand how this works, you’ll actually notice that this is probably used under the hood for a lot of Azure components such as Dev Spaces for AKS, Azure Data Factory Integration Runtime, etc.

Here’s a high-level overview of the architecture:

In our scenario, we will are going to create a Relay namespace that contains a Hybrid Connection. That Hybrid Connection will be subscribing to events on our custom Azure Event Grid topic for new events and relay them to our Hybrid Connection clients.

In the context of our testing, we will connect to our Hybrid Connection and start receiving those relayed events via .NET. (docs)

Writing a test with Azure Relay Hybrid Connection

As a next step, we will create the boilerplate for our integration test which will open a new HybridConnectionsHost for every test and close it when the test finished. This allows us to fully isolate tests.

For our test, I’m using xUnit where I can use IAsyncLifetime to tie in to the test lifecycle and manage our connection host.

Now that our hybrid connection host is listening we can write our test case which will send, receive and deserialize events.

Conclusion

By using Azure Relay with Hybrid Connections you can very easily set up a testing infrastructure to run all your integration tests which can run on any machine as it does not have any dependencies.

Arcus allows you to benefit from some of the work we’ve done before by just plugging it in your tests. Want to get started? Check our docs!