使用Spring进行测试驱动开发

在使用Junit的测试中配置Application

新建maven项目,添加依赖

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>4.0.5.RELEASE</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-test</artifactId>
    <version>4.0.5.RELEASE</version>
</dependency>
<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.11</version>
</dependency>

新建Account类

public class Account {

    private long id;

    private String ownerName;

    private double balance;

    private Date accessTime;



    public long getId() {

        return id;

    }



    public String getOwnerName() {

        return ownerName;

    }



    public double getBalance() {

        return balance;

    }



    public Date getAccessTime() {

        return accessTime;

    }



    public void setOwnerName(String ownerName) {

        this.ownerName = ownerName;

    }



    public void setId(long id) {

        this.id = id;

    }



    public void setBalance(double balance) {

        this.balance = balance;

    }



    public void setAccessTime(Date accessTime) {

        this.accessTime = accessTime;

    }

}
新建AccountDao接口及其实现
public class AccountDaoImpl implements AccountDao {

    private Map<Long,Account> accountMap = new HashMap<Long, Account>();

    {

        Account account1 = new Account();

        account1.setId(100L);

        account1.setOwnerName("John");

        account1.setBalance(100d);

        account1.setAccessTime(new Date());

        Account account2 = new Account();

        account2.setId(101L);

        account2.setOwnerName("Joe");

        account2.setBalance(50d);

        account2.setAccessTime(new Date());

        accountMap.put(account1.getId(),account1);

        accountMap.put(account2.getId(),account2);

    }

    public Account find(long id){

        return accountMap.get(id);

    }

    public void delete(long id){

        accountMap.remove(id);

    }

    public void insert(Account account){

        accountMap.put(account.getId(),account);

    }

    public void update(Account account){

        accountMap.put(account.getId(),account);

    }



}
新建AccountService接口及其实现
public class AccountServiceImpl implements AccountService {

    AccountDao accountDao;



    public void setAccountDao(AccountDao accountDao) {

        this.accountDao = accountDao;

    }



    public void transferMoney(long sourceId, long targetId, double money){

        Account sourceAccount = accountDao.find(sourceId);

        Account targetAccount = accountDao.find(targetId);

        sourceAccount.setBalance(sourceAccount.getBalance() - money);

        targetAccount.setBalance(targetAccount.getBalance() + money);

        accountDao.update(sourceAccount);

        accountDao.update(targetAccount);

    }

    public void depositMoney(long id,double money){

        Account account = accountDao.find(id);

        account.setBalance(account.getBalance() + money);

        accountDao.update(account);

    }

    public Account getAccount(long id){

        return accountDao.find(id);

    }

}
在main/java/resources中添加applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"

       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="accountService" class="service.impl.AccountServiceImpl">

        <property name="accountDao" ref="accountDao"/>

    </bean>

    <bean id="accountDao" class="dao.impl.AccountDaoImpl"/>





</beans>

在src/test/java中新建AccountIntegrationTests类

@RunWith(SpringJUnit4ClassRunner.class)

@ContextConfiguration("/applicationContext.xml")

public class AccountIntegrationTests {

    @Autowired

    private AccountService accountService;

    @Test

    public void accountServiceShouldBeInjected(){

        Assert.assertNotNull(accountService);

    }

}

运行Junit进行测试

示例说明

当运行测试代码时,Spring能够自动创建和管理ApplicationContext.

首先指定可以运行测试类的JunitRunner类。所以用@RunnerWith注解。本例使用SpringJUnit4ClassRunner类作为RunWith类。

在Test类中用@Test注解来表示可以测试的方法。

使用ApplicationContext.xml来配置accountDao和accountService这两个Bean.

除了使用xml配置文件,还可以使用配置类来配置Bean

继承上下文配置

新建Foo类和Bar类

public class Foo {

}
public class Bar {

}

在classpath路径下新建baseContext.xml和subContext.xml配置文件

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"

       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="foo" class="ov.Foo"/>



</beans>
<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"

       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="bar" class="ov.Bar"/>

</beans>

新建BaseTest测试类

@RunWith(SpringJUnit4ClassRunner.class)

@ContextConfiguration("classpath:/baseContext.xml")

public class BaseTest {

    @Autowired

    protected Foo foo;

}

新建SubTest测试类,继承子BaseTest类

@ContextConfiguration("classpath:/subContext.xml")

public class SubTest extends BaseTest{

    @Autowired

    private Bar bar;

    @Test

    public void dependenciesShouldBeAvailable(){

        Assert.assertNotNull(foo);

        Assert.assertNotNull(bar);

    }

}

运行Junit

示例说明

在测试类中继承之后,可以将配置信息以及测试的对象继承。

而Spring TestContext Framwork会自动为测试类配置ApplicationContext.

ApplicationContext缓存

多个测试类指定了完全相同的xml位置或者配置类,那么Spring TestContext FrameWork将只创建一次ApplicationContex实例。该实例存储在一个静态变量中。

在测试中使用事务管理

在测试类上或测试方法上加@Transactional注解,会使类中所有方法或者该方法处在一个事务中,而由于测试的特性,在事务操作后会自动进行回滚。

如果在事务前后想要自动执行某些方法,可以使用@BeforeTransaction和@AfterTransaction注解注解方法。

Mock对象

由于单元测试的理念是只测试单一的对象。而面向对象程序设计难免有依赖项存在,而要测试被测对象还要保证其依赖项也是正确的。然而依赖项的作用有时仅仅是返回特定的数值。所以可以用不同种类的Mock对象来代替这些依赖性,使其可以代替依赖性的作用而正常测试被测对象。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值