Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why can't I set the default factory in Typhoon more than once?

In my unit tests I'm using Typoon and TyphoonBlockComponentFactory objects to instantiate mocks and objects and so on. All my unit tests run at once, in order, and each one sets up its own factory with only the assemblies it needs to run.

It creates that factory and makes it the default factory each time, so classes being tested can instantiate their dependencies from the factory. But the 'makeDefault' method of TyphoonComponentFactory is wrapped in a dispatch_once block, meaning it can only ever happen once over the lifetime of the app.

Why? is some part of my approach fundamentally wrong? I'd like to be able to destroy the Typhoon state somehow in my tearDown methods but I don't know how - can't destroy a singleton!

like image 384
Nick Locking Avatar asked Dec 07 '25 11:12

Nick Locking


1 Answers

The makeDefault method is only intended for integrating Typhoon into legacy code - classes not managed by Typhoon. We now discourage using it elsewhere, because it creates a tight dependency on Typhoon, which can cause these kinds of problems. To mock it out, you'd need to swizzle.

It is very common for one object graph to load another - for example transitioning from one view controller (with injected dependencies) to another. The better way to look up a dependency from Typhoon is to inject the component factory as a dependency. This can be done in the following ways:

  • Have your class conform to TyphoonComponentFactoryAware
  • Inject the assembly, for example:

Ex1: Inject Assembly using property inject

- (id)loyaltyManagementController
{
    return [TyphoonDefinition withClass:[LoyaltyManagementViewController class] 
        properties:^(TyphoonDefinition* definition)
    {
        definition.scope = TyphoonScopePrototype;
        //Inject the TyphoonComponentFactory posing as an assembly
        [definition injectProperty:@selector(assembly)]; 
    }];
}

. . if you follow this approach all of your tests can instantiate their own factories, patchers, override components, etc without calling makeDefault.

Unloading Singletons

Incidentally, you can unload your singletons scoped components by calling the TyphoonComponentFactory's unload method, but this shouldn't be required under normal use.

Update:

All of the above still applies, except that we've now moved the restriction on setting the default factory more than once. This now simply fires a warning.

like image 163
Jasper Blues Avatar answered Dec 09 '25 01:12

Jasper Blues



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!