Results 1 to 4 of 4

Thread: Unit Testing Expression based components

  1. #1
    Join Date
    Nov 2010
    Posts
    2

    Default Unit Testing Expression based components

    Any day I can remove code is a good day so I am excited to start moving our simpler message processors to use expressions instead of java methods. However, I am finding it difficult to unit test them. With the explicit java filters/routers/transformers/etc the unit tests are nicely isolated to the ref'd method with no wiring or mocks. When using expressions instead the expression should still be tested but isolated from the ExpressionEvaluatingFilter/Router/Transformer/etc.

    What if the following interface was added

    Code:
    public interface ExpressionEvaluatingComponent {
    
    	Expression getExpression();
    
    }
    Then all relevant message processing components could implement this so unit tests like the following could be written.

    Code:
    @ContextConfiguration
    @RunWith(SpringJUnit4ClassRunner.class)
    public class PriorityRouterTest {
    
    	@Autowired
    	@Qualifier("priorityRouter")
    	private ExpressionEvaluatingComponent priorityRouter;
    
    	@Test
    	public void testRouter() {
    		Message<String> lowestPriority = MessageBuilder.withPayload("foo").setPriority(1).build();
    		...
    		Message<String> higestPriority = MessageBuilder.withPayload("baz").setPriority(9).build();
    
    		Expression expression = priorityRouter.getExpression();
    		assertEquals("StandardPriorityChannel", expression.getValue(lowestPriority));
    		assertEquals("HighPriorityChannel", expression.getValue(highestPriority));
    	}
    }
    Is there an easier way? I dont see any way to get the expression otherwise except by using an xpath against the config xml.

  2. #2
    Join Date
    May 2007
    Location
    Netherlands
    Posts
    614

    Default

    Interesting thought, but why not just make this an integration test and send a message through (part of) the system?

    The chances of a bug in the framework code are rather small and if your logic is so complex that it should be isolated from the configuration, you should do just that.

  3. #3
    Join Date
    Nov 2010
    Posts
    2

    Default

    My point is that if I had used a method instead of an expression I could write a simple, fast, isolated unit test. All I would have to do is inject the bean and call the method to test it. However by using the expression I have to write a more complex integration test.

  4. #4
    Join Date
    Oct 2005
    Location
    Boston, MA
    Posts
    2,840

    Default

    I agree with your point. In fact, I usually point this out as one of the tradeoffs; expressions might simplify and add flexibility, but referencing a POJO that is also unit-tested in isolation adds some peace of mind. I often point out that if the expression is complex enough that you feel it should be tested, then perhaps you should instead be relying on a POJO anyways. Of course, that's where subjectivity enters the picture. People have different thresholds for what they consider complex enough to require test coverage. Anyone who has accidentally flipped a less-than/greater-than sign (myself included ) might tend toward the side of caution.

    Iwein does raise an important point though. The ability to perform an "integration" test over part of a message flow is really helpful for those high-level "sanity" checks when you do add expression support within the flow.

    One final suggestion that I'd like to offer - more as a compromise - is that you could use placeholders for the actual expressions. For example, you could store the actual expressions in a properties file. Then, you could write unit tests that load those same expressions and execute them with various input values while asserting the expected evaluation results.

    HTH,
    Mark

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •