您的位置:首页 > 编程语言 > Java开发

Spring.Net 中对测试的支持

2011-10-10 16:22 211 查看
Spring团队认为测试是企业软件开发中不可或缺的一部分。

依赖注入的主要好处之一,是你的代码的运行环境或其他子系统, 不太可能有任何隐藏的依赖关系。这使得单元测试中,所测试的对象可以被简单实例化,并设置在单元测试代码中的依赖。您可以使用mock对象(联同其他许多有价值的测试技术)来测试你的代码隔离。如果你遵循了 Spring 的架构建议,就会发现清晰的层次和代码组件将大大方便单元测试。例如,您将能够测试服务层对象的存根或DAO接口,可以在没有访问任何持久性数据的同时,运行单元测试。

真正的单元测试运行起来通常都非常迅速,因为没有运行时基础设施的设置,即数据库,ORM工具,或其他什么。因此,作为你的开发方法论的一部分,强调真正的单元测试将提高您的生产力。

但是,同样重要的是能够执行一些集成测试,使您能够测试的东西,如:
•Spring IoC 容器上下文的正确配置。
•数据访问使用 ADO.NET 或 ORM 工具。这将包括这样的事情,如SQL的正确性 /或NHibernate的XML映射文件。

Spring.NET 支持两种测试环境,对于 NUnit 测试的支持定义在文件 Spring.Testing.NUnit .dll 中,这里使用了 NUnit 2.5.1。对于 MSUnit 的支持定义在 Spring.Testing.Microsoft.dll 中。

在这些程序集中提供了 NUnit 和 MSTest 的父类 AbstractDependencyInjectionSpringContextTests,来支持使用 Spring 容器中的集成测试。
这些超类提供了以下功能:
• Spring的 IoC 容器可以在测试用例的执行之间被缓存。
• 测试实例非常非常透明的依赖注入(这是好的)。
• 适合集成测试的事务管理(这更加爽)。
• 一系列 Spring 特定的继承的实例变量,真的很有用时的集成测试。

上下文管理

Spring.Testing.NUnit 和 Spring.Testing.Microsoft命名空间提供了一致的加载 Spring 上下文和缓存加载的能力。同样Spring 对于测试缓存上下文是很重要的,因为如果你是一个大的项目上工作,启动时间可能会成为一个问题 - 不是因为Spring自身的开销,但因为由Spring容器初始化的对象将采取实例化。例如,一个 50-100 的 NHibernate映射文件项目可能需要10-20秒载入映射文件,并招致之前运行每一个测试案例,在每一个测试用例,会导致降低了整体的测试效率。

为了解决这个问题,AbstractDependencyInjectionSpringContextTests 作为父类,子类必须实现提供上下文定义文件的位置:

protected abstract string[] ConfigLocations { get; }


这个属性方法的实现必须提供一个数组,包含用于配置应用程序的元数据 XML 配置资源的位置。这与普通的 App.config/ Web.config或其他部署配置中指定的地点几乎是相同的。
默认情况下,一旦加载,配置文件中设置将在每个测试用例中重用。这样设置的成本只会产生一次(每个测试fixture),接下来的测试执行就会快得多。在有的情况下,测试可配置的位置,需要重新加载 - 例如,通过改变'脏', 对象的定义或应用对象的状态 - 你可以调用SetDirty()方法,AbstractDependencyInjectionSpringContextTests 造成测试用例重新载入配置重建,然后再执行下一个测试案例的应用程序上下文。

测试用例的依赖注入

当AbstractDependencyInjectionSpringContextTests(子类)加载应用程序的情况下,他们可以选择性地配置通过 Setter 注入你的测试类的实例。所有您需要做的就是定义实例变量和相应的setter方法​​。AbstractDependencyInjectionSpringContextTests 会自动在 ConfigLocations 属性中指定的配置文件的设置中找到相应的对象。
考虑下面的情况,我们有一个类,名字叫 HibernateTitleDao说,执行数据访问逻辑,取得 Title 域对象。

我们要编写集成测试,测试以下几个方面:
•Spring配置,基本上是有关与 HibernateTitleDao 对象的配置一切正确的,现在呢?
•Hibernate 映射文件的配置,是一切正确映射和正确的延迟加载在地方设置?
•逻辑与HibernateTitleDao; 配置这个类的实例执行如预期?

/// <summary>
/// 测试类从 AbstractDependencyInjectionSpringContextTests 派生一下
/// 这个类的 ConfigLocations 提供了用来指定配置文件位置的机制
/// AbstractDependencyInjectionSpringContextTests 使用自动类型装配机制
/// </summary>
[TestFixture]
public class HibernateTitleDaoTests : AbstractDependencyInjectionSpringContextTests {

// this instance will be (automatically) dependency injected
// 用于注入的字段
private HibernateTitleDao titleDao;

// a setter method to enable DI of the 'titleDao' instance variable
// 注入的属性
public HibernateTitleDao HibernateTitleDao {
set { titleDao = value; }
}

[Test]
public void LoadTitle() {
Title title = this.titleDao.LoadTitle(10);
Assert.IsNotNull(title);
}

// specifies the Spring configuration to load for this test fixture
// 配置文件加载的位置
protected override string[] ConfigLocations {
get
{
return new String[] { "assembly://MyAssembly/MyNamespace/daos.xml" };
}
}
}


与此相关的配置参数如下:

<?xml version="1.0" encoding="utf-8" ?>
<objects xmlns="http://www.springframework.net">
<!-- this object will be injected into the HibernateTitleDaoTests class -->
<object id="titleDao" type="Spring.Samples.HibernateTitleDao, Spring.Samples">
<property name="sessionFactory" ref="sessionFactory"/>
</object>
<object id="sessionFactory" type="Spring.Data.NHibernate.LocalSessionFactoryObject, Spring.Data.NHibernate">
<!-- dependencies elided for clarity -->
</object>
</objects>


AbstractDependencyInjectionSpringContextTests 类使用类型自动装配。因此,如果你有同一类型的多个对象的定义,你不能依靠这种方法对那些特定的对象。在这
在这种情况下,您可以使用继承的ApplicationContext 实例变量,并明确查找使用(例如)applicationContext.GetObject(“titleDao”)的一个显式调用。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: