Using Guice for Unit Testing

772 views
Skip to first unread message

christop...@googlemail.com

unread,
Jun 5, 2007, 3:36:06 PM6/5/07
to google-guice
Hello,

in Bob's and Kevin's presentation, they emphasize the possibility to
do unit testing of classes that use Guice by using the constructors
directly, thus skipping Guice.

However, I reckon that Guice's injection mechanisms are in general
very well suited for being used for unit testing. My approach would be
to define one Module that is to be used in the actual environment. And
one that is to be used for unit testing, thus binding to mock-ups,
etc..

Are there circumstances under which the first approach would be
favorable? I am just a little surprised that you advertise not using
Guice in a case that I reckon is perfectly suited for Guice.

hoping for comments,
Christoph

Brian Pontarelli

unread,
Jun 5, 2007, 4:10:40 PM6/5/07
to google...@googlegroups.com

I actually use both approaches....

> in Bob's and Kevin's presentation, they emphasize the possibility to
> do unit testing of classes that use Guice by using the constructors
> directly, thus skipping Guice.
>
This is a good approach for handling complex mock objects such as
interface mocks with EasyMock. Mocks require that you call all the
methods, setup return values, expectations and exceptions and this is
hard when you inject mocks using Guice. It is easier just to create the
mock, call it how it will be called, replay and pass it into the
constructor.

> However, I reckon that Guice's injection mechanisms are in general
> very well suited for being used for unit testing. My approach would be
> to define one Module that is to be used in the actual environment. And
> one that is to be used for unit testing, thus binding to mock-ups,
> etc..
>

I do this when doing more functional tests that will in fact hit the
database, or call another service or hit the web or whatever they might
do. In this case I create a setter (since JUnit has constructor
requirements) and set it to @Inject and then make sure that everything
is in the test module (which can be setup in a @Before method with JUnit
4) or that they have @ImplementedBy guice annotations.

-bp

Kevin Bourrillion

unread,
Jun 5, 2007, 4:55:53 PM6/5/07
to google...@googlegroups.com
On 6/5/07, Brian Pontarelli <br...@pontarelli.com> wrote:

> I actually use both approaches....

Me too.

If I only want to test class A, which depends on interfaces B and C,
it's probably easier and cleaner to not use Guice. Just create mocks
for B and C, and pass them into the real A.

If I want to test how the trio of A, B, and C work as a whole -- a
more interesting test, oftentimes -- then I can still use this
approach. Create a RealC using a MockD and MockE, Create a RealB
using the RealC, MockE, and MockF, etc.

But this can get out of hand. So another alternative is to bang out a
little Module that sets up the environment you want, make an Injector,
and getInstance(A.class) from that. Very convenient!

Does this help?

K

Brian Pontarelli

unread,
Jun 5, 2007, 6:32:20 PM6/5/07
to google...@googlegroups.com
I took it one step further and made a base-class for JUnit 4 that has a
@Before method that sets up Guice. Then in the constructor of my test I
can identify the modules:

@Ignore
public class BaseTest {
private Module[] modules;

public void setModules(Module... modules) {
this.modules = modules;
}

@Before
public void setupGuice() {
Injector i = Guice.createInjector(modules);
i.injectMembers(this);
}
}


public class MyTest extends BaseTest {
private FooService fooService;

public MyTest() {
setModules(new FooModule());
}

@Inject
public void setFooService(FooService fooService) {
this.fooService = fooService;
}

@Test
public void testSomething() {}
}

-bp

christop...@googlemail.com

unread,
Jun 6, 2007, 5:25:15 AM6/6/07
to google-guice
Thanks for the quick and concise answers, they cleared things up for
me.

Reply all
Reply to author
Forward
0 new messages