解决测试代码重复思路

【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;
}