rebus-org / Rebus.ServiceProvider

:bus: Microsoft Extensions Dependency Injection container adapter for Rebus
https://mookid.dk/category/rebus
Other
66 stars 32 forks source link

Testing Rebus in a mocked environment #67

Closed marco-cordeiro closed 1 year ago

marco-cordeiro commented 2 years ago

Hey guys,

Btw great work with Rebus.

Just a bit of context on what my current challenge is. Have a couple of projects where we use Rebus and all those projects use a mocked instance of the IBus, I'm using that to verify that subscriptions are added and that messages are published when they are expected. This uses a custom mock, not a mocking framework. The way I've done this so far was to when I create the WebApplicationFactory I fiddle with the service collection descriptor and replace the IStartBus with my own mocked version. This works great as it allows me to test the all setup without actually testing the Bus infrastructure configuration.

Now I'm trying to upgrade a project from .NET 5 to 6, and one of the big changes is the usage of the Rebus.ServiceProvider 8. And with a bit of surprise I found this is no longer possible, unfortunately the IStarterBus is no longer injected and I can't apply my little work around, it actually seems like there's no reason for this any more as the bus is no longer started there but rather passed on. Digging a bit more I found that the creation of the bus is actually done by the internal class RebusInitializer, which is injected but unfortunately not interfaced, so doesn't allow me to override the interface.

Sorry for the long explanation, just trying to give as much context as possible.

Now the question, is it possible to interface the internal class RebusInitializer so that it's behaviour can be overridden? Or are there alternative suggestions, preferably that don't required a massive amount of work and still allow to test the same things. And using an in-memory transport is I guess an alternative, but is more disruptive as I need to change the configuration and loose the value of verifying is subscriptions are setup as expected.

Thanks in advance for any comments or suggestions. Marco

mookid8000 commented 2 years ago

Sure, I definitely think it would be possible to override RebusInitializer somehow. But I just need to understand precisely what you're trying to achieve here. 🙂

Are you trying to install an alternative IBus implementation (like e.g. FakeBus) in your application's container?

Or do you want to actually run Rebus, only e.g. using an in-mem transport instead of a real one?

marco-cordeiro commented 2 years ago

The purpose is to install a FakeBus.

mookid8000 commented 2 years ago

Could you maybe do something like this? 👉 https://github.com/rebus-org/Rebus.ServiceProvider/blob/master/Rebus.ServiceProvider.Tests/Examples/OverrideBusRegistrationExample.cs

Here I just went and manipulated the ServiceCollection before building the service provider, thus overriding the IBus and dismantling Rebus' startup code (which it runs via its IHostedService registration).

mookid8000 commented 2 years ago

Hi @marco-cordeiro , have you had a chance to take a look at this?