当前位置: 首页 > news >正文

级联测试“级联什么? “

在应用程序中, 当你对子对象进行了一些改变,你肯定不希望需要自己去想着还需要对父对象进行哪些操作,这样是非常繁琐的。好在 NHibernate 提供了级联的功能,你不需要做这些事了。如果你的映射是正确的,你就只需要保存子对象,其他的工作你都不需要理会。

对于一些人,尤其像我这样的,这是一个很大的工作量,这就是为什么我们要测试映射。

[Test()] public void CanCascadeSaveFromCourseToSections() { using (SQLiteDatabaseScope<CourseMapping> Scope = new SQLiteDatabaseScope<CourseMapping>()) { using (ISession Session = Scope.OpenSession()) { Guid ID; Term Term = new Term { Name = "Fall 2009", StartDate = new System.DateTime(2009, 9, 1), EndDate = new System.DateTime(2009, 12, 1) }; //We're not testing the cascade of section -> term here using (ITransaction Tran = Session.BeginTransaction()) { Session.Save(Term); Tran.Commit(); } Session.Clear(); Course Course = new Course { Subject = "SUBJ", CourseNumber = "1234", Title = "Title", Description = "Description", Hours = 3 }; Section Section1 = new Section { FacultyName = "FacultyName", RoomNumber = "R1", SectionNumber = "1", Term = Term }; Section Section2 = new Section { FacultyName = "FacultyName", RoomNumber = "R1", SectionNumber = "2", Term = Term }; Course.AddSection(Section1); Course.AddSection(Section2); //Test saving using (ITransaction Tran = Session.BeginTransaction()) { ID = (Guid) Session.Save(Course); Tran.Commit(); } Session.Clear(); //Check the results using (ITransaction Tran = Session.BeginTransaction()) { Course = Session.Get<Course>(ID); Assert.AreEqual(2, Course.Sections.Count); Assert.AreEqual(1, Course.Sections .Where(S => S.Equals(Section1)).Count(), "Course.Sections does not contain section 1."); Assert.AreEqual(1, Course.Sections .Where(S => S.Equals(Section2)).Count(), "Course.Sections does not contain section 2."); Tran.Commit(); } } } }

上面的测试将确保档你保存 course 的时候,也同样会保存对 section 的操作。下面看看它是如何工作的:

  • 获取一个新的 SQLite 数据库
  • 虽然我们不会测试 term ,但是因为 section 的需要,所以我们也需要在数据库中建立
  • 创建一个 course 和两个 section
  • 保存 course
  • 清空 session
  • 获取到 course
  • 确保它有两个 section

当你从 course 中移除一个 section 将会发生什么呢?当然,任何一个 section 都需要有一个父对象,也就是 course 。请记住,我们在映射里指定的是非空的。更重要的是,现实世界中不会有独立的 section 。所以,当 section 成为孤儿的时候,它将被删除掉,下面我们来进行这样的一个测试:

[Test()] public void CanCascadeOrphanDeleteFromCourseToSections() { using (SQLiteDatabaseScope<CourseMapping> Scope = new SQLiteDatabaseScope<CourseMapping>()) { using (ISession Session = Scope.OpenSession()) { Guid ID; Term Term = new Term { Name = "Fall 2009", StartDate = new System.DateTime(2009, 9, 1), EndDate = new System.DateTime(2009, 12, 1) }; using (ITransaction Tran = Session.BeginTransaction()) { //We're not testing the cascade of section -> term here Session.Save(Term); Tran.Commit(); } Session.Clear(); Course Course = new Course { Subject = "SUBJ", CourseNumber = "1234", Title = "Title", Description = "Description", Hours = 3 }; Section Section1 = new Section { FacultyName = "FacultyName", RoomNumber = "R1", SectionNumber = "1", Term = Term }; Section Section2 = new Section { FacultyName = "FacultyName", RoomNumber = "R1", SectionNumber = "2", Term = Term }; Course.AddSection(Section1); Course.AddSection(Section2); using (ITransaction Tran = Session.BeginTransaction()) { Session.Save(Course); Tran.Commit(); } Session.Clear(); //Test removing Course.RemoveSection(Section1); using (ITransaction Tran = Session.BeginTransaction()) { ID = (Guid) Session.Save(Course); Tran.Commit(); } Session.Clear(); //Check the results using (ITransaction Tran = Session.BeginTransaction()) { Course = Session.Get<Course>(ID); Assert.AreEqual(1, Course.Sections.Count()); Assert.AreEqual(0, Course.Sections .Where(S => S.Equals(Section1)).Count(), "Course.Sections still contains section 1"); Tran.Commit(); } } } }

我希望大家能和我是一样的心态,除了查询测试,当我们写 DAO 层的时候,就要对 NHibernate 进行测试。我们对其他的实体类也都要进行相同类型的测试。

但是…

那么,你肯定在想“这么做太混乱了,肯定无法编译,就算可以,差不多所有的测试都会失败!”是的,如果

http://www.jsqmd.com/news/1131952/

相关文章:

  • openeuler/riscv-kernel在RISC-V生态中的战略意义与价值
  • CentOS YUM 源配置对比:本地 FTP 与网络源(阿里云/华为云)3 方案性能实测
  • Ubuntu服务器vsftpd配置FTPS加密:自签名证书与FileZilla客户端实战
  • Proxmox VE 6.2-4 同机换盘迁移:3步恢复配置与4类启动报错排查
  • Proxmox VE 系统迁移方案对比:DD克隆 vs 配置备份,耗时与风险实测
  • SQL Server 2019 安装失败排查:从日志分析到硬盘扇区兼容性(3类根因)
  • AI网关Requesty:统一入口、自动兜底与成本可感的大模型调度中枢
  • Weblogic 与 Tomcat 后台上传War包对比:3点差异与2个实战避坑指南
  • Oracle 11g 客户端 + PLSQL 14 远程连接配置:5个关键参数详解
  • CHKDSK 与 found.000 深度解析:从文件系统原理到 .chk 文件手动修复
  • 数据分析中的模型评估与选择有哪些常用的方法?
  • LMCache-mindspore架构详解:从原理到实践的完整指南
  • 渗透测试闭环实战:从漏洞发现到防御加固的完整指南
  • IEEE 期刊/会议名缩写查询:5个权威数据库与 3 种自动化方案对比
  • SQL Server 2019+ 自定义函数实战:3种类型对比与性能影响分析
  • LSTM 门控机制解析:3个门如何协同解决RNN梯度消失问题
  • SFR 与 MTF50/MTF50P 对比评测:3 种图像锐度指标在手机摄像头实测中的差异
  • PowerToys v0.80.1 重映射 Ctrl+Space:终极热键冲突解决方案实测
  • 所谓异常机制也就是指的语言平台支持异常这种错误处理模式的机制,比如c#里的Exception对象,try{}catch{}finally{}结构,throw抛出异常的语句,等等,均为c#语言里对异常机
  • 我警告了 329 天
  • Windows 10 21H2+ 系统 HP 打印机驱动 1603 报错:注册表 DisableUserInstalls 值修复指南
  • 反向传播 3 大常见问题:梯度消失、爆炸与 ReLU 死区排查
  • UGUI Mask 与 RectMask2D 性能对比:基于 2021.2.3f1 源码的 2 种裁剪方案实测
  • Unity Timeline 2022.3 精准暂停控制:3种代码方案对比与 Cinemachine 兼容性实测
  • 联想拯救者 2024 款散热实测:双烤 45 分钟 CPU 温度对比 3 款竞品
  • Linux /etc/fstab 配置详解:5个关键参数避免重启后文件系统只读
  • APT 包管理深度解析:从E: Unable to locate package看4种软件源失效场景
  • Linux Anaconda 环境迁移排错:解决3类路径错误与权限问题
  • TC78H660FTG与MK60DN512VLQ10的电机驱动系统设计
  • LSTM 与 GRU 门控机制对比:3 种变体参数量与梯度传播效率分析