Nov 09 2009

NetBeans Unit Test Creation better than Eclipse? And where should unit test live?

Category: Eclipse, Java, TestingPhil @ 5:00 am

I seem to work on a variety of Java applications and find that unit testing is one of the most varied (implementation-wise) pieces of the development process. These applications, created by different development staffs, many which have evolved over the pass few years are all very unique… kind of makes me wonder why? That is a topic for another post!

One debate I always seem to encounter is around where to actually save the unit tests? Should we do in-package testing or rely on the public API. My preferences are pretty simple:

  • Unit test should not be stored with the code, but rather created under a secondary source root. On my early projects, I created a sub-package under each package, called test, to manage the relevant files (tests and data). I later realized that I could simplify the Ant build process and enable in-package testing by creating a separate source tree. I have seen projects commingle the actual source code, unit tests, and even the test data files, all within the single source tree. This defaults the testing strategy to in-package testing, and discourages (or even prevents) API testing. I find this approach rather messy and unclear. This approach also complicates the Ant build process; at some point during the process, the unit tests, supporting classes and files should be separated from the actual deployable content.
  • I like to name my secondary source root tdd. I know it is not widely practiced, but my hope is that if the developers see that TDD directory every time the open up their IDE, the concept might actually wear off! Maybe someday, one developer (hopefully more) will actually be challenged to write their unit tests first. With Eclipse and jUnit 4.x annotations, I seem to always start with my unit test, and sometimes even refactor code from the unit test into the actual class; kind of a high-bread TDD process, but the thought is always there!
  • I also prefer the public API testing strategy verses in-package testing. This line of thinking always takes me back to the Testability Explorer. The concepts behind this metric enforce the idea public API testing and is worth a quick read. Add the Spring Framework to the mix, enabling dependency injection and I see little need for in-package testing. This is typically accomplished by creating a “test” package as the root of the secondary source tree, with sub-packages reflecting the package hierarchy of your classes to be tested. I truly believe that defaulting to in-package testing allows the developers to be very sloppy and even unaware that they are testing a specific internal implementation, rather than externalized behavior presented by the API… This is VERY bad practice in my opinion.
  • If there is a need for in-package testing, then the sub-package structure of the classes to be tested can be recreated under the secondary source tree, maintaining a clean separation between the source and test cases. These test should be considered an exception to the norm, rather than common practice. I would hope for a 90-10 or 80-20 ratio, with a majority of the test falling under the test package root (in-package is the minority).

I am kind of tied to Eclipse as my IDE, but do play with NetBeans every so often. I think I could switch to NetBeans, my only real requirement is that the IDE must have Emacs key bindings; some habits are just too hard to break! NetBeans looks like an pretty good tool and seems to be very responsive on my Ubuntu box; I especially like the way it manages plug-ins.  One interesting thing that NetBeans does (maybe a little better than Eclipse), is manage unit testing. NetBeans will automatically create the secondary source tree, but seems to default to in-package testing. It is very easy to add the additional test package into the package structure to enable API testing. I also like the way that NetBeans separates the Test Libraries from the regular Libraries. I’m not sure how well this would work when you use a tool like Ivy, but does make it more obvious, as to which libraries are used for execution verses unit testing… If you do happen to generate a unit test from an existing class, NetBeans will generate more code than Eclipse. I’m not sure how useful this code is, but it does try to create the object under test, invoke the get() methods and perform assertions on the returned values. Might be more noise that it is worth, and anyway, you should be writing the unit test first!

The bottom line is that Unit testing should be easy and valuable. If it becomes too hard or complicated, it might be time to re-address how the unit test strategy is being implemented.


Nov 08 2009

Eclipse – Ubuntu 9.1 Button Issue…

Category: Eclipse, TestingPhil @ 5:18 pm
This was making me crazy the other night… I did not spend too much time on it, thinking is was just me. But, after upgrading my laptop and encountering the exact same problem, I knew there was more too it. It seemed like only the cancel buttons actually worked; all of the next and finish buttons did absolutely nothing, other then beep!  I soon realized that I could use the tab key and press enter to move to the next screen; but that did not make me very happy.

A quick Google search turned up several people with the same exact problem. It was kind of interesting. The Ubuntu developers did not want to take responsibility for the problem and said it was an Eclipse issue. The Eclipse community said they never had to do anything special for Eclipse to run on Ubuntu; it was looking like a stand off! I did find the official bug report filed with Launchpad.net, it says the problem is resolved. However, without overriding the following variable, Eclipse is not very usable.

export GDK_NATIVE_WINDOWS=1

It also appears that this problem is affecting many other tools on the new 9.1 release as well. This simple fix will get you back into action, without having to wait for the real fix.


Oct 19 2009

Spring Framework Anti-Patterns

Category: Java, Software Development, TestingPhil @ 4:40 pm

Not that I’m a big fan of the whole “Anti-Pattern” concept, but there is some subtle irony in the title of this post; some of my coworkers will actually understand. Sorry about the mystery for the rest of you, but I think this post is really relevant for those trying to use Spring for the first time. After building my first Spring-based application, I was on the fence concerning Spring’s actual value. Obviously, I made lots of mistakes in my first implementation; I think many of the following anti-patterns can typically happen on your first Spring project; my goal is to make you aware of these pitfalls, such that you can skip past the mistakes made by myself and others.

Interesting Thought Tangent?
While looking for the title to my post, I have found a little snippet that calling “Spring a direct attack on J2EE“. I thought this was a unique way of describing the Spring Framework. For sometime now, I have been on the bandwagon to simplify the development practice through Spring (Spring Core, Security and Remoting). I never really thought about Spring as another religious battle front; such as the classic emacs/vi or mac/pc wars. In essence, I was picking a side: No more J2EE! I guess it was not obvious to me before today, as I really can’t escape the J2EE container; I’m are required to deploy in a J2EE container, even though I make no use of its capabilities; a Servlet container is all most of us really need! Just an interesting thought! Agree or Not?

So where to begin, I guess the first question is: Why do you want to use Spring? What service(s) will it provide for you? I think many developers simply wanted to slam it on their resume! Let’s start with the the most obvious use of Spring, Dependency Injection (WIKI, Fowler). I think this is the hardest thing for most developers to actually understand! If you think you are just writing XML code to create your instances rather than writing Java code, you have already missed the boat. I really believe that most developers have not actually taken advantage of DI in their applications.  They just use Spring to create an alternative static (hard-wired) bean creation strategies. Just for fun, I thought I would highlight some anti-patterns I have seen used before and hopefully never again!

Create a Factory.
Factories are so 1990. This is one hurdle that some developers have a tough time understanding. They continue to think about creating objects via factories. There is NO need to ever create a factory when using Spring. Spring is essentially the a super factory, plus it is actually responsible for the life-cycle of those vended objects. There are scenarios where you need to specifically create objects that Spring manages, in a loop for example; but these are very uncommon. The proper way to solve this problem, is to create a bean that is ApplicationContextAware.  When this bean is created (by Spring itself), Spring will set the application context on this bean. Now, you have the ability to ask for any bean that Spring is managing.
Ask Spring for objects.
This is probably the toughest habit to break and is easiest pattern to get stuck in. This is especially true if you are trying to integrate Spring into an existing project and is your first attempt at Inversion of Control. You will have a much better chance understanding these constructs, if you can start from a clean slate (or at least create a bunch of samples). Spring done right, is truly is a different way of thinking. For example, when working with a context-aware Servlet, you fundamentally NEVER need to ask Spring for a single instance; this is almost a perfect example of IOC and DI.  The whole point of DI is the INJECTION. It is not about ASKING for an instance, it is about being GIVEN an instance;  throw in the IOC principle and your bean will be invoked at the RIGHT time to provide the appropriate behavior.
Domain Object DI.
This was an unusual one for me. I recently observed a project that used Spring to created multiple static Singleton factories to vend out a variety of instances, each factory with it’s own Spring context file. Needless to say, this application was far from easy to understand. To my surprise, there was even a factory specifically implemented for creating the business domain objects. Why this was done is still a mystery to me and seems to violate the true spirit of Spring. Why would I ever want to call DomainFactory.getNewWidget() or DomainFactory.getNewGadget()? The configuration had the domain beans defined in a separate Spring context file and oddly, used static methods to initialize specific properties of these new bean instances. There was no way which enabled the XML configuration to be overridden, allowing for different implementations. Worse yet, you were tied to the initialization behavior of the factory methods! Depending on your definition of a domain object, I see very little reason domain object dependency injection.
Use Ant to create Spring Configurations.
This is an interesting use of Ant in a Spring-based application. The idea here is to generate the Spring configuration and properties file from an Ant task, to specifically configure the context files to each deployment environment. They values are essentially baked into the application and unchangeable.  It is bad enough to substitute property file values, but some developers actually substitute bean name references. This might be a little hard to follow, but the Spring XML configuration would define two different implementations of the same basic function, each with its own name. When the application is built, the Ant tasks would substitute ref=”bean1” for some environments and ref=”bean2” for others; everywhere that implementation was referenced in the configuration files. Call me crazy, but I don’t think this what the Spring creators ever intended!

As I have developed a better understanding of Spring and how to take advantage of it features, we have evolved our Spring applications to a state of “environmental awareness”. Using this solution, all of the context and property files are packaged into the application, for all known environments at build time. This enables us to build the deployment image (jar/war file) one time, using simple Ant tasks, no more templates, no more substitutions, no complexity. At execution time, Spring is now intelligent and can determine it’s execution environment; we can use specific property files for specific environments, as well as use alternate implementations (via DI) for each environment. This is where DI really pays off, allowing us to use the appropriate objects, not just properties, but objects for each environment! No code changes, no crazy Ant tasks, you build once and deploy anywhere. I think this is actually pretty slick and what Spring (core functionality) is all about.

I do have to put in a plug in for testability. Taking advantage of jUnit 4.x annotations and Spring integration, makes unit testing a snap. Using the @Resouce annotation to inject everything (instances) you need into your unit test is amazingly elegant; unit testing could not be made any easier. This approach allows us to have highly controlled, customizable execution environments; we can seamlessly manage unique configurations for local development, continuous integration, as well as any actual deployment environment almost magically.


Sep 08 2009

Continuous Deployment with Hudson…

Category: Continuous Integration, Software Development, TestingPhil @ 8:53 pm

Since I was looking through the Hudson plug-in list this week, I decided to try a few more of them. We currently have Hudson continuously deploying a simple web application to a Tomcat instance. Since both Hudson and Tomcat are running on the same server, it was pretty simple to have Tomcat point to the WAR file generated during the build process. Tomcat notices the new WAR file and automatically redeploys the application. Pretty simple and pretty handy; this is about a 100 times easier and faster than dealing with our standard Weblogic deployment process!

So, how do you deploy your application if Hudson is running on a different machine than your Tomcat instance? Fortunately, Hudson provides a plug-in to solve this problem, simply named the Deploy Plug-in. It supports a variety of containers, taking advantage of the Cargo Framework. Can’t get much easier than this, just point to your WAR file and fill in the container information. That’s it! I tried it out today and it worked perfectly. This was a much cleaner approach than adding the logic to the build process.

Having the current code set continuously deployed is a great benefit all by itself. This helps ensure that your application is built correctly and is deployable; How many times have you forgot to add that new JAR file to the WAR, only to discover the failure several days later? Continual deployment also makes the application constantly available to the analysis and test teams. This allows everyone to see the current state of development and bounce through the application to see how it will ultimately work. This early exposure also gives developers a change to resolve issues much earlier in the development cycle. We can achieve more value by adding the integration or system testing to the process as well… Just think how much we could reduce our development and testing cycles with this level of testing?

I have been starting to read about Selenium on the Hudson mailing list and found this interesting blog by Ben Rometsch on “Easy Automated Testing with Hudson and Selenium“. I really liked this picture from the article (hopefully it will spark your interest too!) and truly believe this is what we should be working towards… Maybe this can be one of my next educational adventures!!!


Jul 07 2009

More Firefox Plug-ins – Useful Firebug Extensions

Category: Blogging, TestingPhil @ 7:41 pm

I found an interesting web that has all kinds of great information on website design. A highlighted a couple posts that I thought were very interesting: 10 Unusual Places to Get Design Inspiration and 10 Useful Firebug Extensions. You seriously should click on the design inspiration link, especially if you want to see how creative people can really be; check the beautiful web sites and unforgettable business cards. Truly amazing!

I also did not realize that people were building plug-ins to extend plug-ins! What a concept! I guess that is what makes Firefox such a powerful web browser, tool, platform; there are plug-ins to do about everything. I previously blogged about Firebug and YSlow, but I did not realize that Firebug was also a platform for other developer centric tools, such as HTML validation and code coverage. Someone was nice enough to create a Mozilla Collection for Web Debug Tools, it provides links to all of the referenced plug-ins. 

I recently found a plug-in that I wanted to share as well, called IE Tab. A couple of weeks ago, I was working on a web application and was validating the browser compatibility of our CSS; it was kind of painful switching back and forth between the IE and Firefox, especially since I preferred using Firefox. Fortunately, I discovered IE Tab, which is unfortunately not available on Linux! It simply embeds Internet Explorer in a Firefox tab to render the current page’s content. There will be a little browser icon in the lower right-hand corner of the window; it indicates which browser was used to render the page/tab. Just click on the icon to switch between the two rendering approaches. I think this is much better than having two switch between browsers! Maybe I’m just lazy! There is one small short coming using this approach, it can only use the version of Internet Explorer that you have installed on your computer. I happened to be using IE8 and our testers were using IE6. Needless to say, we had a couple of unexpected issues! Can you believe that IE6 is still being used? I think I would go crazy with out tabbed browsing!


Jun 23 2009

Doing more with jUnit: faster, cleaner unit testing

Category: Java, TestingPhil @ 9:20 pm

These are not really new features, but I bet most developers (like myself) have not given them the attention they deserve! Earlier this month, I read an interesting article on the Atlassian Developer Blog which peaked my jUnit interest. I remember reading about these features when jUnit 4.4 was released a couple of years ago (release notes), but I never took the time to try them out. JUnit included new abilities and concepts, such as Assumptions and Theories. To be real honest, the Assumptions and Theories sound really good in theory, but I’m not sure how practical they are in the real world! How can you argue with definition of a Theory… More flexible and expressive assertions, combined with the ability to state assumptions clearly, lead to a new kind of statement of intent.

First, I’m not sure how well Spring and Theories actually play together. They both need to have their own @RunWith annotation. Second, it is hard enough to get some developers to create a simple unit test! I will have to do some more pondering on Theories. Also, don’t get too carried away with the assumptions without doing some more reading; they have some rather unexpected behavior. Assumptions cause future assertions to pass, irregardless of the asserted value! Interesting?

The real power is in the “Matcher” functionality provided by Hamcrest, creating new capabilities (without writing additional code), a cleaner assertion syntax, creating more readable unit test code. Check out the multitude of convenince Matchers that are provided from Hamcrest. I focused on the power of the assertThat() method. The following code snippet demonstrates a couple of the matchers that I could have used a dozen times in the past and probably implemented my own nasty, non-reusable solution!

	@Test
	public void assertions() {

		final String colors = "color me crazy";
		final Collection<String> colorList = new ArrayList<String>();
		colorList.add("color");

		assertThat(colors, either(containsString("color")).or(containsString("colour")));

		assertThat(colorList, either(contains("color")).or(contains("colour")));

		assertThat("custom error message", colorList, //
				not(either(contains("red")).or(contains("green"))));

		assumeThat(colorList, contains("red"));
		fail("jUnit Still successful!! Does not fail!");
	}

Random Thoughts…

  • jUnit 4.6 was recently released (release notes). I did not see anything exciting in new new release, other that some new integration with JUnit Max.
  • As cool as JUnit Max sounds, it is now dead to me! The subscription fee has jumped to $10 per month… That is more than my XM Radio subscription!!! If continuous testing is really that cool, hopefully, other smart people are working on even better, open-source alternatives!
  • The Spring 2.x framework integration was broken with jUnit 4.5 and required version 4.4. The new 3.x version of Spring, still in beta, works with both 4.5 and 4.6. It actually no longer works with 4.4!


Jun 10 2009

Hudson Continuous Integration and Eclipse Update Sites

I was looking for a development build of the IvyDE plug-in for Eclipse tonight and I stumbled across the Apache Hudson server. You have to check this out. Pretty cool, Hudson running over 150 jobs!  Their build farm consist of both Solaris and Ubuntu servers. What I found most interesting was how they used Hudson for creating an Eclipse update site. I subscribe to the Hudson mailing list, summarized here, to follow what is going on with the project. People seem to use Hudson for a variety of different purposes, such as a cross platform testing tool and even as a deployment tool. I have only been able to get people interested in Hudson as a “Cruise Control” replacement…. but at least it is a good start!

This site also demonstrates how multiple projects can be linked together, triggering builds of dependent downstream projects.  I’m not exactly sure how these jobs were assembled, but at a high-level, Ivy and IvyDE each have its own build loop (job). Each job is responsible for creating build artifacts. After a successful build of either job, a third job is triggered which creates/updates and Eclipse update site.  Pretty slick. (As any FYI, the dev plug-in looks better, new presentation and several new new options)

Another small plug for Continuous Integration. We recently set up something kind of cool (trivial, but cool)! As we continue trying to convince the powers that be, to move away from Weblogic towards Tomcat (or even JBoss), we found a really nice little feature. Since Tomcat and JBoss can hot deploy a new version of the WAR file, just by noticing a difference on the file system, combined with the fact that we can spin up a Tomcat instance in about 2 minutes, we actually created an auto deployment mechanism.  Our Weblogic environment seems so cumbersome in comparison…. We could have built the WAR and deployed in in our build loop, but that would have minimally added another 25 minutes to the loop (let’s just say we have an interesting deployment process). With Tomcat, we did a one time deployment to the location of the WAR file inside the Hudson workspace. Now, with each series of check-ins, we build the WAR as normal and Tomcat instantly deploys it, in seconds! If we were a little more sophisticated, we would write some jUnits to bang against it, making sure we did not break anything or create any new dependencies.  Maybe I will throw that in during my next project!!! I know this integration was possible before (with Weblogic), but no way as simple!  Even better Continuous Integration… on my last project I had Ant spin up an embedded Jetty web server, ran my jUnits against the Clover instrumented code, and finally had Ant shut down Jetty…. Pretty slick, from a code coverage collection perspective…


May 19 2009

How to customize your jUnit Behavior and Interaction

Category: Java, Misc, Testing, UbuntuPhil @ 8:17 pm

I have tried to walk through the jUnit source code a couple of times, trying to figure out how to implement my own behavior; only to give up in frustration (no I did not read the documentation, real developers don’t do that, they Google!) Why would I want to implement my own behavior? Well, it always seems to center around integrating with Spring. I usually want/need to do control the way the context is being created or do something immediately before the context is loaded or as the context is loading; something that might not be possible not possible using a @BeforeClass annotation.

This problem was actually related to my previous blog on Implementing Custom Scopes in Spring. Because I implemented some beans using the session scope, I kind of created a catch-22 scenario;  I have tried to capture the problem in bullet form:

  • Each jUnit test needs the ability to specify the specific test user (role, user info, etc.) that is relevant for that individual test
  • The test user profiles are configured and controlled by a Spring managed bean
  • All beans are lazy-init = true and injected into the unit test using the @Resource annotation
  • The session scope beans need to have the SecurityContextHolder configured with the appropriate principal (test user), before they are created
  • So, the problem is: How do you specify the test user, before the session scope beans are created and injected into the unit test class?

In a normal execution environment, using the Spring Security filters and a Servlet, the SecurityContextHolder would have been assigned using the authenticated principal, before creating any Spring dependencies. Because I created my own custom scopes for unit testing, the SecurityContextHolder was null and the session scope beans constructor was failing an assertion (principal != null). I could have easily fixed this by adding a pre-authenticated user to the SecurityContextHolder, using some static method approach,. However, because my mechanism for handling test users was itself a Spring bean, I had no possible way of specifying before the beans were injected into my unit test.

When jUnit 4.0 was released, it added several new constructs that make some very elegant solutions. I don’t think most developer’s ever look beyond the base jUnit functionality; fortunately it seems to solve 99% of the typical test scenarios. The new constructs are actually specified via annotations, they are the @RunWith and @TestExecutionListeners. My example code, can probably be made a little cleaner, but my main goal was to get the unit tests working. Because you don’t directly create any of these objects, you have to be aware of the timing; implement your customizations at  the correct point in the lifecycle. Another interesting problem, is that you don’t actually create the Spring Context, but you can interact with it via listeners.

First, we need a class which extends DependencyInjectionTestExecutionListener. This base class is required when using Spring and provides several override-able methods. I needed to configure the SecurityContextHolder, before any beans were injected into the unit test; I could accomplish this by utilizing the injectDependencies method. To support my testing needs, I added two (2) properties to the sub-class (this could have been cleaner); one to specify a user from a “user provider” factory, and a simpler one that used the user id of the person running the test. As you can see from the code, before an beans are injected into the unit test, I have access to the Spring context. This allows me to request the “user provider” factory and then request a specific test user. At this point, I can now assign the user to the SecurityContextHolder; all before any of the session scope beans are created.

public class AuthorizedTestExecutionListener extends DependencyInjectionTestExecutionListener {

    private TestUserAuthorization defaultAuthorization;
    private String                junitAuthorization;

    public void setJunitAuthorization(final String junitAuthorization) {
       this.junitAuthorization = junitAuthorization;
    }

    public void setDefaultAuthorization(final TestUserAuthorizationdefaultAuthorization) {
       this.defaultAuthorization = defaultAuthorization;
    }

    @Override
    @SuppressWarnings("PMD.SignatureDeclareThrowsException")
    protected voidinjectDependencies(final TestContext testContext) throws Exception {
       if (StringUtils.isNotBlank(junitAuthorization)) {
           final Authentication login = new UnitTestAuthenticationToken(this.getClass().getSimpleName());
           SecurityContextHolder.getContext().setAuthentication(login);
       }
       else if (defaultAuthorization != null) {
           finalTestUserModuleManager manager = (TestUserModuleManager) testContext.getApplicationContext()
                    .getBean(defaultAuthorization.testUserManager());
           final SecureUserInterface user = manager.find(defaultAuthorization.principal());
           final Authentication login = new UnitTestAuthenticationToken(user);
            SecurityContextHolder.getContext().setAuthentication(login);
        }

       super.injectDependencies(testContext);
    }
}

Next, we need to extend SpringJUnit4ClassRunner. This class is responsible for for creating the Spring test context and  DI listener class.  By over-ridding the  createTestContextManager, you have the opportunity to configure the test execution listeners.  I  also created two custom annotations, TestUserAuthentication and  JUnitAuthentication.  Using either one of these annotations, I could provide run-time meta-data  to my  custom AuthorizedSpringjUnit4ClassRunner; the meta data was then used to configure my custom  AuthorizedTestExecutionListner.

public class AuthorizedSpringjUnit4ClassRunner extends SpringJUnit4ClassRunner {

    public AuthorizedSpringjUnit4ClassRunner(final Class<?> clazz) throws InitializationError {
       super(clazz);
    }

    @Override
    @SuppressWarnings("PMD.ConfusingTernary")

    protected TestContextManager createTestContextManager(final Class<?> clazz) {

       final TestUserAuthorization defaultUser = clazz.getAnnotation(TestUserAuthorization.class);
       final JUnitAuthorization jUnitUser = clazz.getAnnotation(JUnitAuthorization.class);

       final TestContextManager context = super.createTestContextManager(clazz);

       for (final TestExecutionListener l : context.getTestExecutionListeners()) {
           if(AuthorizedTestExecutionListener.class.isAssignableFrom(l.getClass())) {
               if (defaultUser !=null) {
                    ((AuthorizedTestExecutionListener) l).setDefaultAuthorization(defaultUser);
                }
               else if (jUnitUser != null) {
                    ((AuthorizedTestExecutionListener) l).setJunitAuthorization(clazz.getSimpleName());
                }
            }
        }
       return context;
    }
}

Once you understand what all of the pieces do, they are super easy to customize to provide enhanced behavior. I think my solution provided a very clean, elegant solution for providing test specific user profiles, on a test by test basis.

@RunWith(AuthorizedSpringjUnit4ClassRunner.class)
@TestExecutionListeners(AuthorizedTestExecutionListener.class)
@ContextConfiguration(locations = {//
"/com/beilers/resources/spring/contexts/jUnitContext.xml" //
})

public class UnitTestHelper {
...
}


May 17 2009

Unit Testing Custom Spring Scopes

Category: Java, TestingPhil @ 6:45 pm

I recently worked on a JSF-based application that was integrated with Spring, both the Core Framework as well as the Spring Security Framework. I certainly don’t have it all mastered, but the experience has given me multiple topics to blog about! We decided to let Spring manage all of the beans, rather than making JSF manage some of the beans and Spring manager the rest. I liked the consistency and thought it would make unit testing easier. Spring provides two basic scopes, singleton and prototype. When you add Spring Security into the mix, you get two additional scopes, one for session and another for request.

This should have been no big deal. To my surprise, when I wrote my first unit test, I discovered the session and request scopes were not supported; the bean factory threw an unsupported scope exception when I asked for the bean. Googling did not lead to any exact answer, but I found lots of examples; many developers seem to implement a thread scope. I simplified one of the many implementations I found, as I only need to support unit testing.

The first step is to build your own class that implements the Spring Scope interface. I created a generic class, such that I could use it for any custom scope.

public class CustomScopeHandler implements Scope {

     private final Map<String, Object> hBeans = new HashMap<String, Object>();

     public Object get(final String name, final ObjectFactory factory) {
        Object result = null;

        if (hBeans.containsKey(name)) {
            result = hBeans.get(name);
        }
        else {
            result = factory.getObject();
            hBeans.put(name, result);
        }

        return result;
    }

    public Object remove(final String name) {
        Object result = null;

        if (hBeans.containsKey(name)) {
            result = hBeans.get(name);
            hBeans.remove(name);
        }

        return result;
    }

    public String getConversationId() {
        Assert.state(true, “Needs to be implmented – ConversationId”);
        return “N/A”;
    }

    @SuppressWarnings(“PMD.DoNotUseThreads”)
   public void registerDestructionCallback(final String name, final Runnable callback) {
        Assert.state(true, “Needs to be implmented – DestructionCallback”);
    }
}

The next step is to add your custom scopes to the IoC container. Using the Spring CustomScoptConfigurer class, you can easily add as many scopes as you like. Pretty simple! Now you can execute your unit tests as you would have initially expected. One thing to be aware of, this implementation treats beans as if they are singletons. You could easily eliminate the Map and return back new instances on each invocation. It all depends on your specific needs, mine were pretty simple.

      <bean class=”org.springframework.beans.factory.config.CustomScopeConfigurer”>
            <property name=”scopes”>
                  <map>
                        <entry key=”request”>
                              <bean class=”test.scope.CustomScopeHandler” />
                        </entry>
                        <entry key=”session”>
                              <bean class=”test.scope.CustomScopeHandler” />
                        </entry>
                  </map>
            </property>
      </bean> 


Apr 23 2009

Moving from Continuous Integration to Continuous Testing…

Category: Java, TestingPhil @ 1:01 am

I have been following Kent Beck on Twitter for some time, keeping an eye on his jUnit Max product. I think it is a very cool idea, especially with the Eclipse integration. If you have a well written jUnit suite, this could be pretty slick. I only wish Kent would kill the subscription idea; I can’t really blame him for wanting to make money, he just won’t be getting any from me! It is a bummer the tool is not free. It is hard enough to get some developers to build unit tests, now I’m going to charge them a subscription fee to execute the tests… Not happening!

Here was a short little post on the concept. Give it a read and share your thoughts…


Next Page »