How to configure nested dependency for spring tests?

冷暖自知 提交于 2019-12-12 22:26:18

问题


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("~~~~~~~~~~~~~");
    }
}

回答1:


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.



来源:https://stackoverflow.com/questions/41814498/how-to-configure-nested-dependency-for-spring-tests

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!