-
Notifications
You must be signed in to change notification settings - Fork 1
Automated Testing
V11
With HaKafkaNet, tests are a first-class citizen. Depending on the method you use for creating your automations, there are two recommended approaches to automated testing.
For clarity, I will define two types of test.
- Unit Tests - A test that runs in memory and verifies the logic within a single class.
- Integration Test - Also runs in memory, but verifies the entire stack, only mocking external dependencies.
If you implement IAutomation
, IConditionalAutomation
, ISchedulableAutmation
interface, or any of their generic counterparts, as described here, unit tests are recommended.
If your automations are created via the IAutomationRegistry
interface as describe here, integration tests are recommended.
There are no restrictions for unit testing your automations. HaKafkaNet has been designed with heavy use of interfaces. Choose any testing framework you are comfortable with.
If you are not familiar with in-memory integration tests, it is highly recommended to read this documentation from Microsoft as there are several steps needed to enable this type of testing.
First, ensure that your Program
class is visible to your test project either by making internals visible to your test project or adding this line of code to the end of your Program.cs
file which changes your autogenerated Program
class to have a public modifier.
public partial class Program { }
Next, you need a test fixture. Reference this example and create a fixture using a WebApplicationFactory
. You must call the ConfigureForIntegrationTests
method with an IHaApiProvider
object. The example uses Moq
, but you can use any mocking framework of choice. You can optionally pass an IDistributedCache
implementation. An in-memory cache will be used if you do not provide one and should cover most scenarios.
The example also sets the environment to "Test", and is recommended. You should add an "appsettings.Test.json" file to your application (not to the test project).
Note: integration tests will test your entire application, including anything registered in program.cs such as an open telemetry integration. You may not want logs from tests going to your logging infrastructure, or you might, but if you, you will want to configure them differently so that you can tell the difference between logs coming from your tests, and logs coming from your production environment.
Finally, inject the fixture into your test class as demonstrated in the smoke tests.
Most of the time when you write this kind of integration test, you are testing web endpoints. In those scenarios, you would use the fixture to create an HttpClient
. In addition to providing a client which you can use to test HaKafkaNet endpoints (or your own endpoints), your fixture exposes a TestHelper
class with several methods to enable Kafka integration tests specifically the SendState
methods.
This method has 2 arguments. The first is the state that will trigger your automations. The second is the amount of time to delay before returning.
In HaKafkaNet, all automations run asynchronously and in parallel on their own threads. The async tasks created by your automations are not awaited. This ensures that long running processes will not prevent other state changes from being handled. Because the threads are not awaited, you have no way of knowing exactly when they will complete, and as such, you must wait some time for them to complete. By default, the framework will wait 100ms. This number was chosen based on the authors environment. Most of the time, your automations will complete in as little as 10ms. However, setting it this low leads to flappy tests. A hundred milliseconds should cover most situations. You can adjust this number up or down based on your infrastructure.
This sets the default delay used by both the SendState
and AdvanceTime
methods.
Use this method to test any delayable automations. This includes any durable automations.
Note: The
TestHelper
also exposes theFakeTimeProvider
which you can call directly. However, you will need to manually await a delay.
Use this method to make state objects for use with the SendState
methods. Several overloads are provided for creating strongly typed states.
Func<string, CancellationToken, (HttpResponseMessage, HaEntityState?)> Api_GetEntity_Response(string state = "unknown")
This method and its overloads are designed specifically to aid mocking of IHaApiProvider
when your automations rely on a call to get the state of an entity without using the cache. You can see an example of its use here.