I am a software engineer at Google on the Android project and the creator of the Java testing framework TestNG. When I'm not updating this weblog with various software-related posts or speaking at conferences, I am busy snowboarding, playing squash, tennis, golf or volleyball or scuba diving. Cedric is a DZone MVB and is not an employee of DZone and has posted 90 posts at DZone. You can read more from them at their website. View Full User Profile

TestNG and Guice: a Marriage Made in Heaven

12.13.2010
| 4858 views |
  • submit to reddit

TestNG has allowed users to control the instantation of their objects for a while now (around 2007). This is enabled by the IObjectFactory interface:

public interface IObjectFactory extends Serializable {
Object newInstance(Constructor constructor, Object... params);
}

Implement this interface, let TestNG know about your implementation and whenever TestNG needs to instantiate a test class, it will call the newInstance method of your object factory. This allows for a lot of flexibility, and interestingly, this interface appeared in the TestNG distribution long before Dependency Injection became as popular as it is today.

IObjectFactory has been very useful to TestNG users throughout the years, but the emergence of Dependency Injection has made its existence even more important. More and more TestNG users want to inject their test classes with DI frameworks, and over the past few months, I have noticed a sharp increase in Guice users.

IObjectFactory obviously works great with Guice (and Hani and I documented this extensively in our book) but the increased number of questions on the mailing-list prompted me to wonder if I couldn’t make this easier on Guice users.

As it turns out, the answer is yes.

Meet my little new friend, the guiceModule attribute:

@Test(guiceModule = GuiceExampleModule.class)
public class GuiceTest {

@Inject
ISingleton m_singleton;

@Test
public void singletonShouldWork() {
m_singleton.doSomething();
}
}

And that’s it! No need for IObjectFactory or modifying your build files, everything you need is contained in this new guiceModule attribute of the @Test annotation.

Obviously, this module needs to create the necessary bindings for the @Inject annotation to work properly, for example:

public class GuiceExampleModule implements Module {

@Override
public void configure(Binder binder) {
binder.bind(ISingleton.class).to(ExampleSingleton.class)
.in(Singleton.class);
}

}

With this new attribute, using TestNG with Guice has never been easier. Try it for yourself, download the beta and tell us what you think!

From http://beust.com/weblog/2010/12/10/testng-and-guice-a-marriage-made-in-heaven/

Published at DZone with permission of Cedric Beust, author and DZone MVB.

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)

Tags:

Comments

Wujek Srujek replied on Mon, 2010/12/13 - 3:53am

Hi Cedric. Really cool stuff! We have our 'roll your own' dependency framework for test classes using Weld, but this is really cool as well.

Thank you for the framework.

Michael Eric replied on Wed, 2012/09/26 - 3:34pm

I like the itention behind the change – making Guice easier to use in tests. But I see some issues with its current implementation:

* You are introducing one special concept/technology – Guice – into the otherwise very generically usable TestNG. I think these things shouldn’t be mixed up, in especially this adds conceptual complexity for all those people using TestNG but not Guice.
* Currently any classes are allowed as annotation value for “guiceModule”, but actually only classes implementing Module make sense here. So one rather should have something like

Class[] guiceModules() default {};

 

linux archive

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.