I have this problem with unit testing for years. Unit testing should test isolated units, that is, if we use interface/implementation vocabulary, it should test concrete implementation classes. Fine, let's do it. In a code that is the client of the interface, one should mock the interface to suit the tests. That's OK, let us do it where possible, too.But then, in the productions code, there is some place where the actual implementation class is instantiated and used as the-instance-that-implements the interface. It may be factory methods, it can be somewhere else.I have the problem how to actually test this glue between those two, correctly tested in isolation, layers. Using variants of instance of is brittle - not to say, the creator of the actual instance may be smart and choose different implementation based on circumstances. Even if not, it creates that instance using some configuration around.So far, I either do not unit test in strict manner (so I do not do new Foo(directa, directb), but createApp(indirectA, indirectB).getFoo() instead), but that may not be proper unit testing. That does not test all the implementations, that test those-implementations-app-uses. Other approach I may see is to make tests of Foo implementation parametric, having a factory method makeFoo(a,b) and create subclasses for each implementations as well as one which creates those instances via an actual app.Do you know of a good way on how to approach this?In other words, the question may be simply How to (unit) test glue code?
How to unit test correct implementation of an interface is used?
unit testing
In an aftermath of https://vimeo.com/80533536 talk of @jbrains, posted by @ThomasRuiz, I came to this conclusion:Write contract tests (the talk has strict definition of them, I have loose one: tests that only use public API of the class).Stop using new FooImpl(fooConfig) to create implementations of instance that fulfills Foo contract, instead, make it mandatory for your code to have createFoo(fooConfig) factory method to instantiate the Foo contract worker (maybe it should be called hireFoo ;-) ).Your contract tests should test against client.createFoo(testFooConfig). It may be you end up with the need of client being higherClient.createBar(...) itself. This is the week spot of the whole thing. Maybe I should ask.jbrains.ca ... :-\EDIT: Talked with @jbrains. The result is:Your constructors should not create the collaborators. Ideally, they get them injected, like new Foo(collab1, collab2);Applying this to the extreme, it ends up with creating all (!!!) collaborators up front in the topmost layer. See http://blog.thecodewhisperer.com/2011/12/07/refactor-your-way-to-a-dependency-injection-container. See it an app config.Citation new A(new B(new E()), new C(new F(), new G()), new D()) is fine. A creating B, which creates E (and so on) causes problems, in https://twitter.com/jbrains/status/570974691013337089.I finally know why are those DI container out there. Before, I just eschewed them as unnecessary complication.