-
Notifications
You must be signed in to change notification settings - Fork 4.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[QUERY] How to mock EventProcessorClient? #31533
Comments
Hi! Thanks for your question. We just added a sample that outlines the basic approach for mocking the To answer your questions:
Before answering #2, is there anything specific you're looking to test using your mocked |
So, if I understood correctly, the recommendation is to avoid mocking That said, in my case I need to run integration test, meaning I need to start .NET host (with some DI registrations overridden) and test end-to-end flow, so I doubt testing the handlers approach could help.
No, I don't want to rely on undocumented behavior or internals of // Here we are mocking a partition context using the model factory.
PartitionContext partitionContext = EventHubsModelFactory.PartitionContext(
fullyQualifiedNamespace: "sample-hub.servicebus.windows.net",
eventHubName: "sample-hub",
consumerGroup: "$Default",
partitionId: "0");
// Here we are mocking an event data instance with broker-owned properties populated.
EventData eventData = EventHubsModelFactory.EventData(
eventBody: new BinaryData("Sample-Event"),
systemProperties: new Dictionary<string, object>(), //arbitrary value
partitionKey: "sample-key",
sequenceNumber: 1000,
offset: 1500,
enqueuedTime: DateTimeOffset.Parse("11:36 PM"));
// This creates a new instance of ProcessEventArgs to pass into the handler directly.
ProcessEventArgs processEventArgs = new(
partition: partitionContext,
data: eventData,
updateCheckpointImplementation: async (CancellationToken ct) => await Task.CompletedTask); // arbitrary value
mockProcessorClient
.Raise(x => x.ProcessEventAsync += null, processEventArgs); // <-- This cannot be done since ProcessEventAsync is not virtual To summarize, I see 2 options to mock
Are there any other options? Maybe I'm missing something? |
Yes, in general the recommended approach is to avoid mocking the However, now that I have a better understanding of what you're trying to do here I think there are ways you could get around mocking the processor client in a complicated way. For example, the following code would simply call the handler when processing is started
Configuring something like this would probably work for your scenario where it seems you're looking to abstract out all of the processor client behavior and test that your own application code works with the .NET host. Then you could have separate unit tests to cover the cases you need for your handler scenarios. Using live tests with Azure resources would obviously be the most helpful for testing the interaction between the processor and your application, but that obviously has a monetary cost. |
Hi, we're sending this friendly reminder because we haven't heard back from you in 7 days. We need more information about this issue to help address it. Please be sure to give us your input. If we don't hear back from you within 14 days of this comment the issue will be automatically closed. Thank you! |
@m-redding Sorry for the delay with my response.
I didn't quite understand how that is applicable to my scenario. Sure, I can mock To clarify my goal - I'm trying to find a way to "feed" To make it easier, I've created a sample app here that uses public interface IDataStorage
{
void Buffer(ReadOnlyMemory<byte> data);
} In the integration test (the code is here) I simply override private readonly Mock<IDataStorage> _storageMock = new();
private readonly Mock<EventProcessorClient> _processorMock = new();
public IntegrationTests(WebApplicationFactory<Program> factory)
{
_storageMock.Setup(x => x.Buffer(It.IsAny<ReadOnlyMemory<byte>>())).Verifiable();
_ = factory.WithWebHostBuilder(builder =>
{
builder.ConfigureTestServices(services =>
{
services.AddSingleton(_processorMock.Object);
services.AddSingleton(_storageMock.Object);
});
}).CreateDefaultClient();
} The main idea is to verify that the app called |
Hi! No worries. I took a look at the code that you provided in the linked repo and the approach I mentioned above should work for what you're trying to do. After discussing the need for having a simulated run of the To try and explain a little clearer for your specific scenario, you can use any in-memory collection of events that you want to when defining the callback for the mocked You can set up the mocked processor to start a timer when you call |
Hi, we're sending this friendly reminder because we haven't heard back from you in 7 days. We need more information about this issue to help address it. Please be sure to give us your input. If we don't hear back from you within 14 days of this comment the issue will be automatically closed. Thank you! |
Library name and version
Azure.Messaging.EventHubs.Processor 5.7.0
Query/Question
I'm building integration tests for a service (which runs as a worker) using the approach described here. The service receives events from EventHubs partitions using
EventProcessorClient
. The idea is to mockEventProcessorClient
and override its instance in DI container when running within the test host.So far, I was able to mock
BlobClient
andBlobContainerClient
whichEventProcessorClient
uses for checkpointing and partition balancing, and also mocked someEventProcessorClient
's behavior by overriding methods (e.g.ListPartitionIdsAsync
) in inherited class. However, there are 2 questions I'd be very appreciated to get some input about:How to properly mock
ProcessEventAsync
event handler/raise the event from a mock?How to mock
EventHubConnection
(and underlyingTransportClient
/AmqpClient
) with no .NET reflection usage, so it won't connect to EventHubs service?With this setup
EventProcessorClient
fails with the followingsince
InnerClient.CreateConsumer
obviously returnsnull
.Environment
.NET 6.0, Ubuntu Linux (mcr.microsoft.com/dotnet/runtime-deps:6.0-focal-amd64), AKS
Moq
The text was updated successfully, but these errors were encountered: