在 Spring 引导中使用带有 CamelSpringTestSupport 的测试 application.properties 文件
Using test application.properties file with CamelSpringTestSupport in Spring Boot
先决条件
- 阿帕奇 Tomcat 7
- Spring 4.1.5.RELEASE
- Spring 引导 1.2.2.RELEASE
- 阿帕奇骆驼 2.15.1
问题
我正在使用 Spring 使用配置 class 启动,EndpointSetup 也使用该配置。
@SpringBootApplication
@Import({MyConfiguration.class, EndpointSetup.class})
public class MyFatJarRouter extends FatJarRouter { ... }
@Configuration
@ConfigurationProperties(prefix = "camel.route", ignoreUnknownFields = false)
public class MyConfiguration {
private List<String> brokerUrl = new ArrayList<>();
public List<String> getBrokerUrl() {return brokerUrl;}
public void setBrokerUrl(List<String> brokerUrl) {this.brokerUrl = brokerUrl;}
}
生产中的属性将默认从 conf/application.properties 中读取。
我想通过 CamelSpringTestSupport
测试我的路线
所以我尝试了以下方法:
我在 test/resources/config/application.properties 下放置了一个 application.properties(--> 在 class 测试路径中)
然后写道:
public class MyJmsTest extends CamelSpringTestSupport {
@Override
protected AbstractApplicationContext createApplicationContext() {
return new AnnotationConfigApplicationContext(MyFatJarRouter.class);
}
@Test
public void myTest() throws Exception {
...
}
}
在上面的示例中,未从放置在测试文件夹中的 application.properties 中读取配置。
如何在我的 CamelSpringTestSupport 单元测试中读取特定于测试的配置文件?
我使用标准 spring 单元测试解决了这个问题,如下所示:
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = Application.class)
@ActiveProfiles("test") // Load applicaton-test.properties in test/resources/config/application-test.properties
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD) // cleanup spring context because jms broker does not exit properly
public class MyJmsTest {
private static final String MOCK_MY_ENDPOINT = "mock:myEndpoint";
@Autowired
CamelContext context;
@Autowired
ApplicationContext applicationContext;
@Autowired
ProducerTemplate producerTemplate;
@Before
public void configureMocks() throws Exception {
context.getRouteDefinition("MyRoute")
.adviceWith(context, new AdviceWithRouteBuilder() {
@Override
public void configure() throws Exception {
weaveByToString(".*myEndPointId.*")
.replace()
.to(MOCK_MY_ENDPOINT);
}
});
final MockEndpoint endpoint = context.getEndpoint(MOCK_MY_ENDPOINT, MockEndpoint.class);
endpoint.whenAnyExchangeReceived(new Processor() {
@Override
public void process(Exchange exchange) throws Exception {
InputStream inStream = getClass().getClassLoader().getResourceAsStream("xml/my.xml");
String in = context.getTypeConverter().convertTo(String.class, inStream);
exchange.getIn().setBody(in);
}
});
}
@Test
public void synchronousCallBasic_1() throws Exception {
final MyConfiguration MyConfiguration = applicationContext.getBean(MyConfiguration.class);
final String myMessageBody =
context.getTypeConverter().convertTo(String.class, getClass().getClassLoader()
.getResourceAsStream("xml/0010_example.xml"));
final Object myResult = producerTemplate.requestBody(MyConfiguration.getActiveMqSynchronousEndpointUri(), myMessageBody);
assertThat(myResult, notNullValue());
assertThat((String)myResult, is("<example>1</example>"));
}
}
我的回答可能有点晚,但有比破解端点更好的方法。以下解决方案使用 Camel 2.16 中引入的 toD。我写了一个自定义组件"github"(也有官方的),下面是我如何测试它。请注意,我没有使用单个 Camel 专有注释。要注入属性,我可以使用 @SpringBootTest
中的 properties
属性,或者 Spring Boot.
中可用的任何其他标准技术
请注意,我使用 $simple{...}
以避免与 Spring 属性 分辨率冲突。
<rant>
是的,Camel 文档很糟糕!他们像发行说明一样编写它,每个版本都有一个专门的部分,并且似乎没有更新文档以跟上最新版本(未记录以下技术)。想象一下,去一家餐馆要特价菜,服务员却只告诉他们前一天和前一周的特价菜,依此类推。如何对文档进行版本控制?
</rant>
@RunWith(CamelSpringBootRunner.class)
@SpringBootTest
@DirtiesContext(classMode = AFTER_EACH_TEST_METHOD)
public class GitHubRouteTest {
@Autowired
private CamelContext camelContext;
@Autowired
private ProducerTemplate template;
@Autowired
private GitHubClient gitHubClient;
@Test
public void testGitHubClientInvoked() throws InterruptedException {
template.sendBodyAndHeader("direct:start", "whatever",
"endpoint", "commits/test/test?username=test&password=test");
verify(gitHubClient).getCommitsForARepo(eq("test"), eq("master"), eq("test"), eq(20));
}
@SpringBootApplication
public static class TestApplication {
public static void main(String[] args) {
new SpringApplicationBuilder()
.sources(TestApplication.class)
.web(false)
.run(args);
}
@Bean
public RouteBuilder testRoute() {
return new RouteBuilder() {
@Override
public void configure() throws Exception {
from("direct:start")
.toD("github:$simple{in.header.endpoint}");
}
};
}
@Bean
public GitHubClient mockGitHubClient() {
GitHubClient mock = Mockito.mock(GitHubClient.class);
return mock;
}
}
}
我解决了这个问题,我发现了很多注释 here,现在测试属性被正确注入:
@RunWith(CamelSpringBootRunner.class)
@SpringBootTest
@ActiveProfiles("test")
@EnableAutoConfiguration
@ComponentScan
@ContextConfiguration()
public class MessageDeliveryTest{
}
此外,测试属性文件需要命名为application-{env}.properties,其中"env"是此处使用的配置文件。例如。为了测试属性文件应该是 application-test.properties
先决条件
- 阿帕奇 Tomcat 7
- Spring 4.1.5.RELEASE
- Spring 引导 1.2.2.RELEASE
- 阿帕奇骆驼 2.15.1
问题
我正在使用 Spring 使用配置 class 启动,EndpointSetup 也使用该配置。
@SpringBootApplication
@Import({MyConfiguration.class, EndpointSetup.class})
public class MyFatJarRouter extends FatJarRouter { ... }
@Configuration
@ConfigurationProperties(prefix = "camel.route", ignoreUnknownFields = false)
public class MyConfiguration {
private List<String> brokerUrl = new ArrayList<>();
public List<String> getBrokerUrl() {return brokerUrl;}
public void setBrokerUrl(List<String> brokerUrl) {this.brokerUrl = brokerUrl;}
}
生产中的属性将默认从 conf/application.properties 中读取。
我想通过 CamelSpringTestSupport
测试我的路线所以我尝试了以下方法:
我在 test/resources/config/application.properties 下放置了一个 application.properties(--> 在 class 测试路径中)
然后写道:
public class MyJmsTest extends CamelSpringTestSupport {
@Override
protected AbstractApplicationContext createApplicationContext() {
return new AnnotationConfigApplicationContext(MyFatJarRouter.class);
}
@Test
public void myTest() throws Exception {
...
}
}
在上面的示例中,未从放置在测试文件夹中的 application.properties 中读取配置。
如何在我的 CamelSpringTestSupport 单元测试中读取特定于测试的配置文件?
我使用标准 spring 单元测试解决了这个问题,如下所示:
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = Application.class)
@ActiveProfiles("test") // Load applicaton-test.properties in test/resources/config/application-test.properties
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD) // cleanup spring context because jms broker does not exit properly
public class MyJmsTest {
private static final String MOCK_MY_ENDPOINT = "mock:myEndpoint";
@Autowired
CamelContext context;
@Autowired
ApplicationContext applicationContext;
@Autowired
ProducerTemplate producerTemplate;
@Before
public void configureMocks() throws Exception {
context.getRouteDefinition("MyRoute")
.adviceWith(context, new AdviceWithRouteBuilder() {
@Override
public void configure() throws Exception {
weaveByToString(".*myEndPointId.*")
.replace()
.to(MOCK_MY_ENDPOINT);
}
});
final MockEndpoint endpoint = context.getEndpoint(MOCK_MY_ENDPOINT, MockEndpoint.class);
endpoint.whenAnyExchangeReceived(new Processor() {
@Override
public void process(Exchange exchange) throws Exception {
InputStream inStream = getClass().getClassLoader().getResourceAsStream("xml/my.xml");
String in = context.getTypeConverter().convertTo(String.class, inStream);
exchange.getIn().setBody(in);
}
});
}
@Test
public void synchronousCallBasic_1() throws Exception {
final MyConfiguration MyConfiguration = applicationContext.getBean(MyConfiguration.class);
final String myMessageBody =
context.getTypeConverter().convertTo(String.class, getClass().getClassLoader()
.getResourceAsStream("xml/0010_example.xml"));
final Object myResult = producerTemplate.requestBody(MyConfiguration.getActiveMqSynchronousEndpointUri(), myMessageBody);
assertThat(myResult, notNullValue());
assertThat((String)myResult, is("<example>1</example>"));
}
}
我的回答可能有点晚,但有比破解端点更好的方法。以下解决方案使用 Camel 2.16 中引入的 toD。我写了一个自定义组件"github"(也有官方的),下面是我如何测试它。请注意,我没有使用单个 Camel 专有注释。要注入属性,我可以使用 @SpringBootTest
中的 properties
属性,或者 Spring Boot.
请注意,我使用 $simple{...}
以避免与 Spring 属性 分辨率冲突。
<rant>
是的,Camel 文档很糟糕!他们像发行说明一样编写它,每个版本都有一个专门的部分,并且似乎没有更新文档以跟上最新版本(未记录以下技术)。想象一下,去一家餐馆要特价菜,服务员却只告诉他们前一天和前一周的特价菜,依此类推。如何对文档进行版本控制?
</rant>
@RunWith(CamelSpringBootRunner.class)
@SpringBootTest
@DirtiesContext(classMode = AFTER_EACH_TEST_METHOD)
public class GitHubRouteTest {
@Autowired
private CamelContext camelContext;
@Autowired
private ProducerTemplate template;
@Autowired
private GitHubClient gitHubClient;
@Test
public void testGitHubClientInvoked() throws InterruptedException {
template.sendBodyAndHeader("direct:start", "whatever",
"endpoint", "commits/test/test?username=test&password=test");
verify(gitHubClient).getCommitsForARepo(eq("test"), eq("master"), eq("test"), eq(20));
}
@SpringBootApplication
public static class TestApplication {
public static void main(String[] args) {
new SpringApplicationBuilder()
.sources(TestApplication.class)
.web(false)
.run(args);
}
@Bean
public RouteBuilder testRoute() {
return new RouteBuilder() {
@Override
public void configure() throws Exception {
from("direct:start")
.toD("github:$simple{in.header.endpoint}");
}
};
}
@Bean
public GitHubClient mockGitHubClient() {
GitHubClient mock = Mockito.mock(GitHubClient.class);
return mock;
}
}
}
我解决了这个问题,我发现了很多注释 here,现在测试属性被正确注入:
@RunWith(CamelSpringBootRunner.class)
@SpringBootTest
@ActiveProfiles("test")
@EnableAutoConfiguration
@ComponentScan
@ContextConfiguration()
public class MessageDeliveryTest{
}
此外,测试属性文件需要命名为application-{env}.properties,其中"env"是此处使用的配置文件。例如。为了测试属性文件应该是 application-test.properties