在Spring引入Java Config机制之后,我们会越来越多的利用@Configuration来注册Bean,而且Spring Boot更遍及地利用了这一机制,其提供的大量Auto Configuration大大简化了设置事情。那么问题来了,如何确保@Configuration和Auto Configuration凭据预期运行呢,是否正确地注册了Bean呢?本章举例测试@Configuration和Auto Configuration的要领(因为Auto Configuration也是@Configuration,所以测试要领是一样的)。
例子1:测试@Configuration
我们先写一个简朴的@Configuration:
@Configuration public class FooConfiguration { @Bean public Foo foo() { return new Foo(); } }
然后看FooConfiguration是否可以或许正确地注册Bean:
public class FooConfigurationTest { private AnnotationConfigApplicationContext context; @BeforeMethod public void init() { context = new AnnotationConfigApplicationContext(); } @AfterMethod(alwaysRun = true) public void reset() { context.close(); } @Test public void testFooCreation() { context.register(FooConfiguration.class); context.refresh(); assertNotNull(context.getBean(Foo.class)); } }
留意上面代码中关于Context的代码:
假如你看Spring Boot中关于@Configuration测试的源代码会发明和上面的代码有点纷歧样:
public class DataSourceAutoConfigurationTests { private final AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(); @Before public void init() { EmbeddedDatabaseConnection.override = null; EnvironmentTestUtils.addEnvironment(this.context, "spring.datasource.initialize:false", "spring.datasource.url:jdbc:hsqldb:mem:testdb-" + new Random().nextInt()); } @After public void restore() { EmbeddedDatabaseConnection.override = null; this.context.close(); }
这是因为Spring和Spring Boot都是用JUnit做测试的,而JUnit的特性是每次执行测试要领前,劳务派遣管理系统,城市new一个测试类实例,而TestNG是在共享同一个测试类实例的。
例子2:测试@Conditional
Spring Framework提供了一种可以条件节制@Configuration的机制,即只在满意某条件的环境下才会导入@Configuration,这就是@Conditional。
下面我们来对@Conditional做一些测试,首先我们自界说一个Condition FooConfiguration:
@Configuration public class FooConfiguration { @Bean @Conditional(FooCondition.class) public Foo foo() { return new Foo(); } public static class FooCondition implements Condition { @Override public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) { if (context.getEnvironment() != null) { Boolean property = context.getEnvironment().getProperty("foo.create", Boolean.class); return Boolean.TRUE.equals(property); } return false; } } }
该Condition判定Environment中是否有foo.create=true。
假如我们要测试这个Condition,那么就必需往Environment里添加相关property才可以,在这里我们测试了三种环境:
FooConfigurationTest:
public class FooConfigurationTest { private AnnotationConfigApplicationContext context; @BeforeMethod public void init() { context = new AnnotationConfigApplicationContext(); } @AfterMethod(alwaysRun = true) public void reset() { context.close(); } @Test(expectedExceptions = NoSuchBeanDefinitionException.class) public void testFooCreatePropertyNull() { context.register(FooConfiguration.class); context.refresh(); context.getBean(Foo.class); } @Test public void testFooCreatePropertyTrue() { context.getEnvironment().getPropertySources().addLast( new MapPropertySource("test", Collections.singletonMap("foo.create", "true")) ); context.register(FooConfiguration.class); context.refresh(); assertNotNull(context.getBean(Foo.class)); } @Test(expectedExceptions = NoSuchBeanDefinitionException.class) public void testFooCreatePropertyFalse() { context.getEnvironment().getPropertySources().addLast( new MapPropertySource("test", Collections.singletonMap("foo.create", "false")) ); context.register(FooConfiguration.class); context.refresh(); assertNotNull(context.getBean(Foo.class)); } }
留意我们用以下要领来给Environment添加property:
context.getEnvironment().getPropertySources().addLast( new MapPropertySource("test", Collections.singletonMap("foo.create", "true")) );