数据访问层的单元测试

发表于:2016-3-25 10:18

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:jerrylsxu    来源:51Testing软件测试网采编

  数据访问层在分层结构,比较常见. 有时可能是数据访问模块. 假设数据访问层后端是数据库,那我们如何测试他们的呢? 有时实际这种测试是集成测试了.
  有时数据库里还有一些逻辑,触发器,约束等. 个人十分不建议把业务逻辑放在数据库里实现. 最常见的数据库表的操作create, read, update和delete(简称CRUD)
  , 例如我们需要测试某个Add方法,在这个测试方法完成后, 希望这条测试数据清除掉. 这样做是 为了不影响其它的测试方法也访问同一数据库对象.
  首先,我们可以使用.net 2.0中提供的TransactionScope类, 下面的代码基于MsTest的单元测试:
1:      [TestClass]
2:      public class DbTestBase
3:      {
4:          private TransactionScope scope;
5:
6:          [TestInitialize]
7:          public void SetUp()
8:          {
9:              this.scope = new TransactionScope();
10:          }
11:
12:          [TestCleanup]
13:          public void TearDown()
14:          {
15:              this.scope.Dispose();
16:          }
17:      }
  上面代码我们看到在标记TestInitialize特性SetUp方法中创建TransactionScope的实例,在TestCleanup特性TearDown方法中调用TransactionScope的Dispose方法.  然后我们继承这个测试基类:
1:      [TestClass]
2:      public class DateBaseTesting : DbTestBase
3:      {
4:          /// <summary>
5:          /// Test Insert record to database
6:          /// </summary>
7:          /// <seealso cref="http://www.cnblogs.com/wintersun"/>
8:          /// <remarks>Any database modification will be roll back</remarks>
9:          [TestMethod]
10:          public void TestAddWithEmployeeRepository()
11:          {
12:              //arrange
13:              var employee = this.CreateNewEmployee();
14:              var employRepository = RepositoryHelper.GetEmployeeRepository();
15:
16:              //act
17:              employRepository.Add(employee);
18:              employRepository.Save();
19:
20:              //assert
21:              var employeelist =
22:                 employRepository.Repository.Find(e => e.EmployeeID == employee.EmployeeID);
23:              Assert.IsNotNull(employeelist);
24:              CollectionAssert.AreEqual(new List<Employee>() { employee }, employeelist.ToList());
25:          }
26:
27:
28:          private Employee CreateNewEmployee()
29:          {
30:              var employee = new Employee
31:              {
32:                  ManagerID = 2,
33:                  ContactID = 3,
34:                  Title = "Developer",
35:                  BirthDate = new DateTime(1965, 1, 1, 0, 0, 0),
36:                  HireDate = DateTime.Now,
37:                  Gender = "M",
38:                  MaritalStatus = "M",
39:                  ModifiedDate = DateTime.Now,
40:                  NationalIDNumber = "2",
41:                  rowguid = new Guid(),
42:                  CurrentFlag = true,
43:                  VacationHours = 2,
44:                  SickLeaveHours = 3,
45:                  SalariedFlag = false,
46:                  LoginID = "myworkbase\\peter"
47:              };
48:              return employee;
49:          }
50:
51:      }
  上面的TestAddWithEmployeeRepository中场景是数据访问层基于EntityFramework的Repository模式, 这里的操作是先是创建实体,然后是提交.  实际中可以是您的任何代码块,ADO.NET或其他的数据访问组件. 当我们执行这个单元测试后,这个TransactionScope将被释放. 之前插入的那条记录将被清除.
  假设你不想用基类, 只是简单在某个方法中, 可以这样做:
1:          [TestMethod]
2:          public void TestWrapTransactionScope()
3:          {
4:              WrapTransactionScope(() => TestAddWithEmployeeRepository());
5:          }
6:
7:          /// <summary>
8:          /// Wraps the transaction scope for unit testing
9:          /// </summary>
10:          /// <param name="action">The action method</param>
11:          /// <remarks>author http://www.cnblogs.com/wintersun </remarks>
12:          public void WrapTransactionScope(Action action)
13:          {
14:              using (var scope = new TransactionScope())
15:              {
16:                  action();
17:              }
18:          }
21/212>
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号