Handling Swing Events in JUnit Test

I have a networked Swing Java application with multiple "Players" represented as game objects, each with its own communication flow. The application has a "Team" object that manages all of the player's objects. Several UI components listen for events dispatched to players via the Team object.

In my design, the command object fires all events on the Swing thread using invokeLater, so the rest of my application doesn't need to worry about threading issues. However, I don't know how I can test the Team class in a JUnit test.

A bit more background. I first had a Team object that fired its events on player object streams (without switching streams). The unit test command succeeded, but I got into many threading issues in my UI with invokeLaters and syncronized all over the place. Then I decided to simplify the streaming model by firing Team object events on the Swing thread, but now the unit test command fails because it doesn't accept events. What to do?

The solution that comes to mind is injecting an extra object on top of the command that executes the flow switch and keeps the original unit test intact, but I don't like the idea of ​​introducing complexity into the production code to make the unit test succeed.

+1


source to share


3 answers


When I tested JUnit with help EventQueue.invokeLater

, I separated myself from this evil static. Create an interface with methods invokeLater

is isDispatchThread

. For production, the implementation should simply go to EventQueue

. Use your own thread for testing (which can be customized and demolished for each test).

Some other random tips:



  • Keep the GUI as thin as possible.
  • Keep threading from everything else and everything else from threading.
  • Be suspicious of anything that claims to be thread safe.
+4


source


Perhaps you can use easymock to isolate the classes you want to test and have mock objects receive events and check if they are fired.

I would recommend EasyMock: http://www.easymock.org/



From your history it seems like your unittests are more integration tests and are very complex. If this happens, try to simplify and isolate. You have probably read http://junit.sourceforge.net/doc/testinfected/testing.htm

Hope this helps.

+2


source


The solution that comes to mind is to inject an extra object on top of the command that executes the flow switch and keep the original unit test intact, but I don't like the idea of ​​introducing complexity into production code to make the unit test a success.

I don't know if this is the case here, but I often find that the "complexity" I add is actually a higher level of abstraction that improves the code.

The original idea behind mock objects was not to simplify unit testing, but rather to "discover the interface", create interfaces that represent abstractions in your ubiquitous language, rather than working at the API level.

+2


source







All Articles