Writing tests that fail, as it turns out, is pretty simple. Let's pick that low-hanging fruit:
package com.mybiz.jms; import org.springframework.jms.core.JmsTemplate; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.testng.AbstractTestNGSpringContextTests; import org.testng.annotations.BeforeClass; import org.testng.annotations.Test; import javax.annotation.Resource; import javax.jms.DeliveryMode; @ContextConfiguration(locations = { "classpath:com/mybiz/jms/spring-jms-demo.xml"} ) public class BasicConfigTest extends AbstractTestNGSpringContextTests { @Resource private JmsTemplate myTemplate; @BeforeClass public void setUp() throws Exception { System.out.println("Run BasicConfigTest..."); assert applicationContext != null; } @Test public void testConfig() throws Exception { System.out.println("testConfig..."); assert myTemplate.getDeliveryMode() == DeliveryMode.PERSISTENT; assert myTemplate.getTimeToLive() == 10000; assert myTemplate.isExplicitQosEnabled(); assert myTemplate.isPubSubDomain(); assert myTemplate.isSessionTransacted(); assert myTemplate.isPubSubNoLocal(); } }
I don't need to tell you that, without any other work, this test will fail; let's take on something a bit less trivial. The test assumes a Spring configuration which resides in the same logical directory tree as the class. Here's that spring-jms-demo.xml configuration:
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.springframework.org/schema/beans" xsi:schemalocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"> <import resource="spring-context.xml"/> <import resource="spring-jms.xml"/> </beans>
The first import establishes context-based annotation, scanning for components and property placeholder
resolution, which will combine to help us reuse the generic Spring-JMS configuration (the second import). This spring-context.xml file is the beginning of my application-specific configuration:
<beans xmlns:context="http://www.springframework.org/schema/context" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.springframework.org/schema/beans" xsi:schemalocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd"> <context:annotation-config> <context:component-scan base-package="com.mybiz.jms"/> <context:property-placeholder location="com/mybiz/jms/spring-jms.properties" system-properties-mode="OVERRIDE"/> </context:annotation-config> </beans>
That file uses a properties file (spring-jms.properties) that backfills the generic Spring-JMS configuration with more of our application specifics:
# URL for connection to broker - use testing URL: brokerURL=vm://localhost?async=false&broker.persistent=false # # messages will remain in broker for 10 seconds timeToLive=10000 # # 1 - non-persistent / 2 - persistent deliveryMode=2 # # Specify concurrency of 40 for starters sessionCacheSize=40 # # big perf boost, minimal risk (see comments in spring-jms.xml) useAsyncSend=true # # support for flexibility on per-send basis explicitQosEnabled=true # # concern is around a blocking consumer (see comments in spring-jms.xml) dispatchAsync=true # # txn around sends sessionTransacted=true # # just in case pubSubNoLocal=true # # must specify this if it's a topic; default is false pubSubDomain=true # # txn around receives acknowledge=transacted # # destination for topic destination=theTopic
Finally, I need two listeners that are referenced by the Spring-JMS configuration:
package com.mybiz.jms; import org.springframework.stereotype.Service; @Service public class MyListener {} // works for now; but this will need some work
package com.mybiz.jms; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; import javax.jms.ExceptionListener; import javax.jms.JMSException; @Component public class MyExceptionListener implements ExceptionListener { private final Logger log = LoggerFactory.getLogger(getClass()); public void onException(JMSException e) { log.error("JMS error", e); } }
Now the unit test will run successfully; there's no (meaningful) output to show you, and for that matter the test and listeners are along the lines of "what's the simplest thing that would work" - it's really only done to demonstrate that all the moving parts are in place and that I've used them correctly so far. In my next, I'll start adding on some target functionality and look for ways to test it.
No comments:
Post a Comment