dotnet / orleans

Cloud Native application framework for .NET
https://docs.microsoft.com/dotnet/orleans
MIT License
10.03k stars 2.02k forks source link

Simple DI for unit tests? #8790

Open alexdresko opened 8 months ago

alexdresko commented 8 months ago

When configuring an application to use Orleans, you .UseOrleans(...) and everything just works, including dependency injection.

When you need to write unit tests that make use of Orleans, my understanding is that you have to use TestClusterBuilder.

The problem, based on my understanding, is that the cluster created by TestClusterBuilder has its own dependency injection container, completely isolated from the container I've set up for my unit tests.

So, for example, if I register a singleton in my test's container and in the TestClusterBuilder, there will be two different singletons, depending on where the singleton is resolved from.

If my unit test already sets up a DI container, how do I tell TestClusterBuilder to just use that container? If it matters, we're using NUnit and Autofac.

Here's an example of what that kinda looks like:

[SetUp]
public void Setup()
{
    var webApplicationBuilder = WebApplication.CreateBuilder();
    webApplicationBuilder.Host.UseServiceProviderFactory(new AutofacServiceProviderFactory())
        .ConfigureContainer<ContainerBuilder>(c =>
        {
            c.RegisterType<Something>().AsSelf().SingleInstance();
        });

    var app = webApplicationBuilder.Build();

    var testClusterBuilder = new TestClusterBuilder(1);
    testClusterBuilder.AddSiloBuilderConfigurator<TestSiloConfigurations>();
    TestCluster = testClusterBuilder.Build();
    TestCluster.Deploy();
}

public class TestSiloConfigurations : ISiloConfigurator
{
    public void Configure(ISiloBuilder siloBuilder)
    {
        siloBuilder.ConfigureServices(services =>
        {
            services.AddSingleton<Something>();
        });
    }
}

I created this StackOverflow post to get some answers, and no one replied, even after I added a 150 point bounty. Maybe I didn't explain the problem well enough. I do know that I've spent a considerable amount of time trying to figure out how to get this stuff working, and I'm out of ideas.

I'd love it if you could just tell me what I'm missing.. or at least confirm that what I want isn't possible.

lukaskostial commented 6 months ago

I'm struggling with a similar problem. I'd like to unit test my grain which has some deps passed via constructor. I'd like to use TestCluster but to mock these dependencies. Is there any way how to register my mocks?

bbehrens commented 6 months ago

The Orleans discord channel is a fantastic spot to get almost instant feedback for these types of questions. https://discord.gg/KjAHJ5EV