-
Notifications
You must be signed in to change notification settings - Fork 29
-
In a regular ASP.NET project, for example, you can set up your DI via Startup.cs:
services.AddSingleton<IServiceA, ServiceA>() .AddSingleton<IServiceB, ServiceB>();
and in the test project, you can do this to override the configured DI for the main project (see here):
builder.ConfigureTestServices(services => services.AddSingleton<IServiceA, MockServiceA>());
Is there a way to do something similar with this library? I have tried the following:
Main project (has no knowledge of test project):
// Composition.cs public partial class Composition; // Startup.cs DI.Setup("Namespace.Composition").Bind<IServiceA>().As(Lifetime.Singleton).To<ServiceA>().Root<IServiceA>();
Test project (references main project):
// BaseTest.cs DI.Setup("Namespace.Composition") .Bind<IServiceA>().As(Lifetime.Singleton).To(_ => Mock.Of<IServiceA>).Root<IServiceA>();
Inspecting the Composition instance and stepping through the code during debugging shows that the test setup isn't overriding the original as I'd like. Is there an approach I should use?
Beta Was this translation helpful? Give feedback.
All reactions
Replies: 1 comment 1 reply
-
I've added sample tests in this repository.
Pure.DI is not a DI container, but a source code generator. All code is generated at compile time. It's the same with tests. In the example you will find integration tests, I guess your question is more related to them.
This example generates a test composition based on settings from the Lib library:
private void Setup() => DI.Setup(nameof(MyServiceTests)) // Based on the Composition setup from the Lib namespace .DependsOn("Lib.Composition") // Overrides some instances using mocks .Bind<IOutput>().To(_ => _output.Object) .Bind<IInput>().To(_ => _input.Object) // Exposing a test instance as the composition root .Root<IService>("Service");
In the test composition, some of the objects are replaced by Mocks. And the test object is defined as the root of the composition.
Beta Was this translation helpful? Give feedback.
All reactions
-
👍 1
-
I ended up moving all the functionality of the static method into a class of its own to make things easier (time is limited at the moment).
Some context for my original question:
I'm writing an AWS Lambda function handler built as an executable assembly.
// Startup.cs internal static void SetupDependencyInjection() { DI.Setup(nameof(Composition))... } // Function.cs public class Function { private static async Task Main() { Startup.SetupDependencyInjection(); await LambdaBootstrapBuilder.Create(...).Build().RunAsync(); } public static async Task Handler(..., ILambdaContext context) { await using var composition = new Composition(); var abc = composition.Resolve<IAbcService>(); abc.DoSomething(); ... } }
I had been hoping to replace/override the bindings set up in the main project with mocks, but based on what you said, it is impossible to achieve.
In the end, I did this:
// Function.cs public static async Task Handler(..., ILambdaContext context) { await using var composition = new Composition(); var handler = composition.Resolve<IFunctionHandler>(); await handler.HandleAsync(..., context); } // Handler.cs public class Handler(IServiceA serviceA, IServiceB serviceB) { private readonly IServiceA serviceA = serviceA; private readonly IServiceB serviceB = serviceB; public async Task HandleAsync(..., ILambdaContext context) { ... } }
and tested Handler as normal with mocks.
Beta Was this translation helpful? Give feedback.