数据访问层的单元测试
作者:网络转载 发布时间:[ 2016/3/28 11:25:33 ] 推荐标签:软件测试 单元测试
上面的代码演示了, 我们用Action委托实现另一个方法包装一下目标方法使其在TransactionScope块中.
我们还可以使用xUnit 类库 这实现同样的操作, 这里使用是xUnit 1.8版本. 还有MbUnit,NUnit的[RollBack]特性与这个类似. 如果您还不熟悉怎么使用xUnit请先看这里介绍. 下面的代码使用 xUnit 代码变得更加简洁:
1: /// <summary>
2: /// Database unit testing with xUnit demo
3: /// </summary>
4: /// <remarks>http://wintersun.cnblogs.com </remarks>
5: public class TestDbWithxUnit
6: {
7: [Fact]
8: [AutoRollback]
9: public void Test_Add_One_Enity()
10: {
11: //arrange
12: var employee = this.CreateNewEmployee();
13: var employRepository = RepositoryHelper.GetEmployeeRepository();
14:
15: //act
16: employRepository.Add(employee);
17: employRepository.Save();
18:
19: //assert
20: var employeelist =
21: employRepository.Repository.Find(e => e.EmployeeID == employee.EmployeeID);
22: Assert.NotNull(employeelist);
23: Assert.Equal(new List<Employee> { employee }, employeelist.ToList());
24: }
25: }
上面的代码我们只需在方法上加一个AutoRollback的Attribute可以了, 注意你先需要引用xunit.extensions.dll
当然,标准的单元测试我们完全隔离数据库, 数据访问组件在单元测试中不应该访问数据库. 我们使用Mock框架来实现对数据库的隔离, 如下代码演示了我们使用Moqv4.0.20926 和 xUnit 来实现的单元测试:
1: [Fact]
2: public void TestWithMoq()
3: {
4: //arrange
5: var mock = new Mock<IRepository<Employee>>();
6: Employee employee = this.CreateNewEmployee();
7: var list = new List<Employee>() { employee };
8:
9: mock.Setup(ep => ep.Add(It.IsAny<Employee>()))
10: .Callback(()=>Console.WriteLine("Add()"));
11: mock.Setup(ep => ep.Find(It.IsAny<Expression<Func<Employee, bool>>>()))
12: .Returns(list);
13: mock.Setup(ep => ep.Save())
14: .Callback(() => Console.WriteLine("Save()"));
15: var employeeRespository = mock.Object;
16:
17: //act
18: employeeRespository.Add(employee);
19: employeeRespository.Save();
20:
21: //verify method
22: mock.Verify(ep => ep.Add(It.IsAny<Employee>()));
23: mock.Verify(ep => ep.Save());
24:
25: //assert
26: var employeelist =
27: employeeRespository.Find(e => e.EmployeeID == employee.EmployeeID);
28: Assert.NotNull(employeelist);
29: Assert.Equal(new List<Employee> { employee }, employeelist.ToList());
30: }
Employee是实体类, IRepository<T>是一个统一数据访问interface, 实现martinfowler的Repository模式; 上面的代码Mock了其中的Add,Save方法, 在调用后并做了Verify,确认之前Mock的方法有被调用到, 后的部分才是Assert语句块. 代码很简单.
除了使用Mock框架, 我们还可以使用依赖注入容器来注入一个具体的Fake对象实现对访问数据库的隔离, 我们使用Unity 2.1 来实现:
1: [Fact]
2: public void TestWithDIContainer()
3: {
4: //arrange
5: var employee = this.CreateNewEmployee();
6: var list = new List<Employee>() { employee };
7: var employeeRespository = GetRepositoryInstance("for testing");
8:
9: //act
10: employeeRespository.Add(employee);
11: employeeRespository.Save();
12:
13: //assert
14: var employeelist =
15: employeeRespository.Find(e => e.EmployeeID == employee.EmployeeID);
16: Assert.NotNull(employeelist);
17: Assert.Equal(new List<Employee> { employee }, employeelist.ToList());
18: }
19:
20: private IRepository<Employee> GetRepositoryInstance(string name)
21: {
22: //Initial container
23: var container = new UnityContainer();
24: container.RegisterType<IRepository<Employee>, EFRepository<Employee>>();
25: container.RegisterType<IRepository<Employee>, FakeRepository<Employee>>("for testing");
26: //....
27: return container.Resolve<IRepository<Employee>>(name);
28: }
上面的代码为了演示的简便, 我们实现创建容器注册对象在一个private方法中; 您也可以使用其它IOC/DI的容器. FakeRepository<Employee>是一个实现了IRepository<T>的具体类, 在其内部可以在内存中操作实体,或是其它方式. 具体看您的需求了.
以上所有是我们介绍对数据访问层或数据库进行单元测试的解决方法:
1. 使用TransactionScope类实现测试方法回滚
2. 使用xUnit类库的AutoRollback特性实现自动回滚
3. 使用Moq框架来实现隔离数据库的访问
4. 使用Unity容器注入Fake对象来实现隔离数据库的访问
本文内容不用于商业目的,如涉及知识产权问题,请权利人联系SPASVO小编(021-61079698-8054),我们将立即处理,马上删除。
相关推荐
iOS单元测试mocha、chai、sinon和istanbul实现百分之百的单元测试覆盖率关于单元测试的总结及思考编写更好的Java单元测试的7个技巧Android单元测试框架Robolectric3.0介绍(一)使用Kiwi单元测试总结单元测试如此重要,为什么你不知道Python单元测试??使用装饰器实现测试跳过和预期故障对Controller的单元测试写好单元测试的10个技巧单元测试的重要性Angular单元测试系列??Component、Directive、Pipe 以及ServiceAndroid单元测试的整理提升单元测试体验的利器--Mockito使用总结iOS UnitTest单元测试Vue的单元测试探索(二)
更新发布
功能测试和接口测试的区别
2023/3/23 14:23:39如何写好测试用例文档
2023/3/22 16:17:39常用的选择回归测试的方式有哪些?
2022/6/14 16:14:27测试流程中需要重点把关几个过程?
2021/10/18 15:37:44性能测试的七种方法
2021/9/17 15:19:29全链路压测优化思路
2021/9/14 15:42:25性能测试流程浅谈
2021/5/28 17:25:47常见的APP性能测试指标
2021/5/8 17:01:11热门文章
常见的移动App Bug??崩溃的测试用例设计如何用Jmeter做压力测试QC使用说明APP压力测试入门教程移动app测试中的主要问题jenkins+testng+ant+webdriver持续集成测试使用JMeter进行HTTP负载测试Selenium 2.0 WebDriver 使用指南