解决测试代码重复思路
【1】问题
在之前的测试类中,每个测试方法都有以下两行代码:
ApplicationContext ac =
new ClassPathXmlApplicationContext("bean.xml");
IAccountService as =
ac.getBean("accountService", IAccountService.class);
这两行代码的作用是获取容器,如果不写的话,直接会提示空指针异常。所以又不能轻易删掉。
【2】解决思路分析
在前面,我们试过把变量字段提取到类的成员变量域中,发现还有瑕疵!
首先我们明确需要程序要帮我们创建容器。但显然,Junit 是无法实现的,因为它自己都无法知晓我们是否使用了 Spring 框架,更不用说帮我们创建 Spring 容器。
不过好在,Junit 给我们暴露了一个注解,可以让我们替换掉它的运行器。
这时,我们需要依靠 Spring 框架,因为它提供了一个运行器,可以读取配置文件(或注解)来创建容器。我们只需要告诉它配置文件在哪就行了。
④、Spring 整合 JUnit 配置
【1】导入Spring整合JUnit的坐标
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.0.2.RELEASE</version>
</dependency>
须知: Spring 整合 JUnit 需要 坐标 spring-test,也就是以下注解所需的 jar 包.
【2】@RunWith 替换原有运行器
运行器:带有 main 方法的类。
使用 JUnit 提供的一个注解把原有的 main 方法的类替换成 Spring 提供的 SpringJUnit4ClassRunner 类,该类会为程序创建容器。
有了容器,那么 IAccountService 对象的注入就合理了!
@RunWith(SpringJUnit4ClassRunner.class)
public class AccountServiceTest { }
【3】@ContextConfiguration 指定 bean.xml 的位置
告知 Spring 的运行器,Spring 的 IoC 容器创建是基于 xml 还是注解,并且说明 xml 的位置
注:当我们使用 Spring 5.x 版本的时候,要求 JUnit 的 jar 必须是4.12及以上
@RunWith(SpringJUnitClassRunner.class)
@ContextConfiguration(classes= {"SpringConfiguration.class"} )
//@ContextConfiguration(location="classpath:bean.xml") 此处没有使用xml配置 bean。
public class AccountServiceText() { }
@ContextConfiguration 注解:
属性 | 作用 |
locaions location | 用于指定配置文件的位置。如果是类路径下,需要用 classpath |
classes | 当不使用 xml 配置时,用于指定注解的类。 |
【4】注入数据
之前,我们在 AccountServiceTest 类中每一个都要写 获取容器、获取业务层 对象,为了方便我们把它们提取到了外边,变成了下面这样:
public class AccountServiceTest {
private ApplicationContext ac;
private IAccountService as;
@Before
init() {
ac = new ClassPathXmlApplicationContext("bean.xml");
as = ac.getBean("accountService", IAccountService.class);
}
@Text
textFindAll() {
//...
}
@After
destory() {}
}
需求又来了:能不能不需要手动编码来获取容器! 并且注入数据呢!这时我们遇到了一个问题:在 @Text 单元测试方法无法提供一个运行器来支持创建容器,所以需要替换运行器!于是想到了以上 Spring 整合 JUnit 的方法!
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:bean.xml"})
public class AccountServiceTest {
@Autowried
private IAccountService as;
}