zcz527 / autofac

Automatically exported from code.google.com/p/autofac
Other
0 stars 0 forks source link

Allow to test modules (TestContainerBuilder) #332

Closed GoogleCodeExporter closed 8 years ago

GoogleCodeExporter commented 8 years ago
Hi, i often want to test if a module correctly registered all types.

Currently the only way to do that is to build up a container and resolve that 
component which was registered by the module. The problem is that this also 
invokes the code which is in the components + IStartable. And the second 
problem is that if you use RegisterAssemblyTypes you have a problem in the test 
assembly when you want to register only specific types of the test assembly 
which are specific the current test. This is why i requested #305.

While thinking about that i got a better idea. Why not make a 
TestContainerBuilder which is derived (or have the same base class) as the 
default ContainerBuilder and a TestContainer. This way i can do the test like 
this:

    var builder = new TestContainerBuilder();

    builder.RegisterModule<MyModule>();

    var container = builder.Build();

    Assert.True(container.CanResolve<MyClass>());
    Assert.Equel(3,container.Count<IMyInterface>());

Maybe that also would work without the TestContainer and directly with the 
TestContainerBuilder. 

The seconds problem can then be solved via:

    var builder = new TestContainerBuilder();

    // If a RegisterAssemblyTypes is called with the passed in assemblie,
    // use this type list instead of assembie.GetTypes()
    builder.OverrideAssembly(assebly,new type[]{typeof(Foo),typeof(Bar)});

    builder.RegisterModule(new MyModule(assembly));

    .....

Original issue reported on code.google.com by lanwin...@gmail.com on 23 Jun 2011 at 9:15

GoogleCodeExporter commented 8 years ago
Interesting ideas. On testing modules with IStartable included:

var builder = new ContainerBuilder();
var container = builder.Build();
var updater = new ContainerBuilder();
updater.RegisterModule<MyModule>();
updater.Update(container);

The container can now be checked for registrations without the IStartables 
being initialised. Will look at adding a helper method to get the same 
behaviour more directly.

Thanks!

Original comment by nicholas...@gmail.com on 2 Jul 2011 at 11:49

GoogleCodeExporter commented 8 years ago
Ok - now:

builder = new ContainerBuilder();
builder.RegisterModule<MyModule>();
var container = builder.Build(ContainerBuildOptions.IgnoreStartableComponents);

I'll mark this issue as closed, although I think your test harness idea is very 
good. I would like to see it available somewhere (perhaps contrib?) where it 
might get developed some more before including anything in core.

Thanks again for your always-valuable input! 

Nick

Original comment by nicholas...@gmail.com on 3 Jul 2011 at 12:11

GoogleCodeExporter commented 8 years ago
Thanks for looking at it!

But IStartable is only half the problem. More problematic is the code of the 
constructors which is invoked while resolve.

Maybe another idea would be to make ContainerBuildOptions.ReturnTypesOnly. 
Which dose not returns an instance but the type of the instance instead.

Original comment by lanwin...@gmail.com on 3 Jul 2011 at 9:01

GoogleCodeExporter commented 8 years ago
If you're interested in checking which type would come back from a Resolve() 
operation, rather than just using IsRegistered(), you could do something based 
on:

IComponentRegistration registration;
container.ComponentRegistry.TryGetRegistration(
  new TypedService(typeof(IMyService)),
  out registration);
Assert.AreEqual(someType, registration.Activator.LimitType);

Apart from cases where delegate activators are used, this will give you the 
precise type that would provide a service, without creating any instances.

Cheers!
Nick

Original comment by nicholas...@gmail.com on 3 Jul 2011 at 10:18