Someone sent me a question via email and I figured I'd pass it along
to this group. Here is my friend's question:
"There's a page that summarizes Guice Best Practices. It compares
field, method and constructor injection. One of the stated cons of
field injection says "Your class is not testable!". Why is that? Can't
you inject fields with different values for tests by writing a
different Module class that is used by tests?"
So when the best practices page says 'not testable', is it more
accurate to say 'hard to test without using a Guice module in your
tests' ? I understand that with constructor or method injection, I
don't even need Guice in my tests. I could just create mock POJOs and
call setter methods myself. But with field injection, I'd need to
either use a module with Guice, or else resort to reflection tricks to
set the fields.
What you're saying is accurate. Also note that with field injection you enter a gray zone when it comes to thread safety and safe publication, since you can't make your fields final and Guice doesn't inject the values until after the constructor executes. In a sense, field injection is the "autowiring" of injection: simple to begin with but surprisingly difficult to get right in the long term.
But it works great for examples. :-)
Robbie
On Tue, Jul 22, 2008 at 3:24 PM, Eric M. Burke <burke.e...@gmail.com> wrote:
> Someone sent me a question via email and I figured I'd pass it along > to this group. Here is my friend's question:
> "There's a page that summarizes Guice Best Practices. It compares > field, method and constructor injection. One of the stated cons of > field injection says "Your class is not testable!". Why is that? Can't > you inject fields with different values for tests by writing a > different Module class that is used by tests?"
> So when the best practices page says 'not testable', is it more > accurate to say 'hard to test without using a Guice module in your > tests' ? I understand that with constructor or method injection, I > don't even need Guice in my tests. I could just create mock POJOs and > call setter methods myself. But with field injection, I'd need to > either use a module with Guice, or else resort to reflection tricks to > set the fields.
On Tue, Jul 22, 2008 at 6:24 AM, Eric M. Burke <burke.e...@gmail.com> wrote:
> So when the best practices page says 'not testable', is it more > accurate to say 'hard to test without using a Guice module in your > tests' ? I understand that with constructor or method injection, I > don't even need Guice in my tests. I could just create mock POJOs and > call setter methods myself. But with field injection, I'd need to > either use a module with Guice, or else resort to reflection tricks to > set the fields.
That's correct. We should update that doc--"hard to test by hand." I actually kind of like field injection. It's concise. You don't have to worry about circular references. You don't have to worry about user code executing during injection (with the exception of providers). Of course, you can't access those fields from your constructor... that kind of sucks.
On Tue, Jul 22, 2008 at 6:53 AM, Robbie Vanbrabant <
robbie.vanbrab...@gmail.com> wrote: > What you're saying is accurate. Also note that with field injection you > enter a gray zone when it comes to thread safety and safe publication, since > you can't make your fields final and Guice doesn't inject the values until > after the constructor executes. In a sense, field injection is the > "autowiring" of injection: simple to begin with but surprisingly difficult > to get right in the long term.
I don't think there are any thread safety concerns here. Injection happens all in one thread. You can make the fields final. Of course, you'll have to initialize them to some default value, but Guice will overwrite that value and you'll get the same semantics that you get if the field's set in the constructor ( http://jeremymanson.blogspot.com/2008/07/immutability-in-java-part-3....).
On Tue, Jul 22, 2008 at 4:20 PM, Bob Lee <crazy...@crazybob.org> wrote:
> On Tue, Jul 22, 2008 at 6:53 AM, Robbie Vanbrabant < > robbie.vanbrab...@gmail.com> wrote:
>> What you're saying is accurate. Also note that with field injection you >> enter a gray zone when it comes to thread safety and safe publication, since >> you can't make your fields final and Guice doesn't inject the values until >> after the constructor executes. In a sense, field injection is the >> "autowiring" of injection: simple to begin with but surprisingly difficult >> to get right in the long term.
> I don't think there are any thread safety concerns here. Injection happens > all in one thread. You can make the fields final. Of course, you'll have to > initialize them to some default value, but Guice will overwrite that value > and you'll get the same semantics that you get if the field's set in the > constructor ( > http://jeremymanson.blogspot.com/2008/07/immutability-in-java-part-3.... > ).
Thanks for the link, that's something I didn't know. Which somehow confirms my concerns, though.
On Tue, Jul 22, 2008 at 8:07 AM, Robbie Vanbrabant <
robbie.vanbrab...@gmail.com> wrote: > Thanks for the link, that's something I didn't know. Which somehow confirms > my concerns, though.
I actually shouldn't have mentioned the semantics of final. The important thing is that all injection happens in a single thread, so there are no concurrency concerns w/ field vs. constructor injection.
> I don't think there are any thread safety concerns here. Injection happens > all in one thread. You can make the fields final. Of course, you'll have to > initialize them to some default value, but Guice will overwrite that value > and you'll get the same semantics that you get if the field's set in the > constructor > (http://jeremymanson.blogspot.com/2008/07/immutability-in-java-part-3....).
Wow, is this really true? It goes against everything I thought I'd known with threading concerns & publishing. I also had no clue that 'setAccessible' let you overwrite final fields -and- did it safely with threading.