Singleton components


This is a continuation of the ticket on GitHub

While migrating from 0.3.9 to 0.5.18 and moving some “singleton components” to global resources, I noticed that this suddenly required a different testing pattern.

Whereas previously one could inject a fake component into the view directly, now you need to mock out the global resources. I did like that the views could be created and tested as “pure” functions previously.



You can still replace components, both using the pattern I showed in that GitHub ticket and using normal components, but the resolution order has changed. i.e. whereas in version 0.3 you would pass stubs after the component

app = App(components=[AComponent(), AComponentStub()])

in 0.4+ you have to pass stubs first

app = App(components=[AComponentStub(), AComponent()])

That said, yeah, testability is the reason I came up with SingletonComponent in our app. Being able to stub out a component at test setup time is really valuable and a lot clearer than trying to mock stuff out.

Unfortunately, the SingletonComponent doesn’t solve the problem for components that ought to be singletons but that depend on other components (i.e. singletons that have to be instantiated lazily). I did come up with a LazySingletonComponent at one point but it turned out pretty ugly so I threw it away.


Yes, stubbing out the components (whatever kind), is still really valuable. But from what I understood from the GitHub thead, @tom was also questioning if global resources could replace (global/singleton) components. They can, but at the cost of having non-pure views.