21274

How to configure nested dependency for spring tests?

Question:

The error I'm getting has to do with parsing the properties before injecting in to the Test class. I end up with ${property.name} when the property is injected. However the configuration of the Test class seems very wrong considering there are nested dependencies.

Specific error: Caused by: java.net.URISyntaxException: Illegal character in authority at index 8: https://${sqs.endpoint}

I've got a config class to load a specific prop for a @Bean:

@Configuration public class AWSConfig { private static final Logger LOGGER = LoggerFactory.getLogger(AWSConfig.class); private @Value("${sqs.endpoint}") String endpoint; @Bean(name = "awsClient") @Primary public AmazonSQSAsyncClient amazonSQSClient() { AmazonSQSAsyncClient awsSQSAsyncClient = new AmazonSQSAsyncClient(); awsSQSAsyncClient.setEndpoint(endpoint); return awsSQSAsyncClient; } }

Here's where this @Bean is injected:

@Component public class SqsQueueSender { private static final Logger LOGGER = LoggerFactory.getLogger(SqsQueueSender.class); private final QueueMessagingTemplate queueMessagingTemplate; @Autowired @Qualifier("awsClient") AmazonSQSAsyncClient amazonSQSAsyncClient; public SqsQueueSender(AmazonSQSAsync amazonSQSAsyncClient) { this.queueMessagingTemplate = new QueueMessagingTemplate(amazonSQSAsyncClient); } //take advantage of convertAndSend to send POJOs in appropriate format public void send(String queueName, String message) { this.queueMessagingTemplate.convertAndSend(queueName, MessageBuilder.withPayload(message).build()); } }

This all seems to work, at least the app starts up and prints logs from either location. I am unable to get a unit test running against this code though. I can't figure out how to set up the config correctly. Here's the latest iteration of the test class:

@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(loader=AnnotationConfigContextLoader.class) public class SqsQueueSenderTest { @Configuration static class ContextConfiguration { private @Value("${sqs.endpoint}") String endpoint; @Bean(name = "awsClient") @Primary public AmazonSQSAsyncClient amazonSQSClient() { AmazonSQSAsyncClient awsSQSAsyncClient = new AmazonSQSAsyncClient(); awsSQSAsyncClient.setEndpoint(endpoint); return awsSQSAsyncClient; } @Bean public SqsQueueSender sqsQueueSender() { SqsQueueSender sqsQueueSender = new SqsQueueSender(amazonSQSClient()); // set up the client return sqsQueueSender; } } @Autowired SqsQueueSender sqsQueueSender;// = new SqsQueueSender(new AmazonSQSAsyncClient()); private static final Logger LOGGER = LoggerFactory.getLogger(SqsQueueSenderTest.class); // attributes for in-memory sqs server AmazonSQSClient client; SQSRestServer server; SQSRestServerBuilder sqsRestServerBuilder; @Before public void startup() { LOGGER.info("Building in-memory SQS server"); this.server = sqsRestServerBuilder.withPort(9324).withInterface("localhost").start(); this.client = new AmazonSQSClient(new BasicAWSCredentials("x", "x")); client.setEndpoint("http://localhost:9324"); client.createQueue("test"); LOGGER.info("Finished building in-memory SQS server"); } @After public void shutdown() { LOGGER.info("Stopping in-memory SQS server"); server.stopAndWait(); LOGGER.info("Finished stopping in-memory SQS server"); } @Test public void testSending() { LOGGER.info("~~~~~~~~~~~~~"); sqsQueueSender.send("test", "new message"); LOGGER.info("The current queues are" + client.listQueues().toString()); LOGGER.info("~~~~~~~~~~~~~"); } }

Answer1:

Joe ,first of all put your connection properties in a resource for testing:

src/test/resouces/test.properties

Then add this to the Test class definition:

@PropertySource( value={"classpath:test.properties"}, @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(loader=AnnotationConfigContextLoader.class) public class SqsQueueSenderTest {

And finally in your Configuration class add this bean:

@Configuration static class ContextConfiguration { @Bean public static PropertySourcesPlaceholderConfigurer properties() throws Exception { return new PropertySourcesPlaceholderConfigurer(); } }

Dont forget to place to place 'sqs.endpoint' url in your properties file.

This in my opinion is one of the cleaner ways of injecting your properties into the test class.

Recommend

  • ProgressBar visibility issue
  • Dynamodb requestHandler acception
  • ValueRequiredException during RSS feed parsing in Retrofit
  • Problems with Angular, CORS and Spring
  • Logging @Controller Requests Spring Boot
  • Spring Java @DateTimeFormat
  • SpringBoot CRUD Repository fail to Autowire
  • Spring Boot Application Unable to start?
  • Applying custom annotation advice to spring data jpa repository
  • @Autowired for @ModelAttribute
  • Animate a CAShapeLayer's subclass custom property based on the path property
  • GridView breaks while scrolling
  • MongoDb aggregation
  • How to use RequestBodyAdvice
  • Set the selected item in dropdownlist in MVC3
  • Error when parsing timestamp with pandas read_csv
  • Is it possible to access block's scope in method?
  • why overloaded new operator is calling constructor even I am using malloc inside overloading functio
  • C++ Partial template specialization - design simplification
  • How to use an array of arrays with array_map(…) in PHP?
  • Different response to non-authenticated users and AJAX calls
  • jQuery show() function is not executed in Safari if submit handler returns true
  • How to draw moving and Running sine wave chart using JFree chart in java?
  • output of program is not same as passed argument
  • Incrementing object id automatically JS constructor (static method and variable)
  • Eraser for UIBezierPath
  • How to limit post in wp_query
  • Upload files with Ajax and Jquery
  • Build own AppleScript numerical error handling
  • AngularJs get employee from factory
  • Java static initializers and reflection
  • Exception on Android 4.0 `android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode)`
  • Change div Background jquery
  • Bitwise OR returns boolean when one of operands is nil
  • Is there any way to bind data to data.frame by some index?
  • Django query for large number of relationships
  • Why is Django giving me: 'first_name' is an invalid keyword argument for this function?
  • How can I use `wmic` in a Windows PE script?
  • How to push additional view controllers onto NavigationController but keep the TabBar?