使用 Selenium 和 ASPX.net,如何将 Mock 传递给代码隐藏?

Using Selenium and ASPX.net, how to pass a Mock to codebehind?

我 运行 Selenium 针对我的本地 IIS 来提供页面和验证应用程序行为。我想在我的一些测试中模拟数据库。我已经使用了一个接口"proxy",所以我想用一个Mock替换我的实现,这样我就可以只验证调用逻辑层时使用的参数。有人可以推荐有关该主题的不错的资源/教程/书籍吗?

场景:在 Page_Load() 中填充下拉列表。 Page.IsPostBack 没有测试,所以它总是被重置,即使在用户提交表单之后(在事件处理程序之前)也是如此。我正在编写一个回归测试来证明提交的值实际上传递给了 Provider --> Repository(并通过 extension --> database ).

谢谢!

背景

通常,Moq 在单元测试期间使用(即一个单独的 class 或被测试的系统层),而 Selenium 意味着浏览器自动化测试,并且您的 Selenium 单元测试将超出您的 WebForm 的进程。模拟的一个主要好处是它提供了验证/监视被测系统的能力,这通常需要对要测试的 class 进行进程内实例化,并直接注入模拟依赖项 - AFAIK这将在 运行 进程外时丢失(当使用 Se 测试时,您希望在部署状态下测试应用程序)。

IMO WebForms 页面并不真正有助于使用 Moq 进行这种单元测试,因为:

  • 很难直接和孤立地创建 WebForm,因为存在大量环境依赖项 - 例如需要模拟页面生命周期,并提供 HttpContextSession
  • System.Web.Page 不是为构造函数或 Setter 注入设计的

不过,话虽如此,还是有希望的:

  • 可以应用改造来获得 Dependency Inversion principle mechanism 使用 WebForms 的能力。
  • 虽然在 运行 进程外您将失去 Moq 的验证功能,但您仍然可以使用 Moq 来存根您的依赖项并 return 伪造数据到 WebForm (例如 IRepository 依赖项的存根)。然而,为了执行验证,您将需要找到另一种机制来记录对您的依赖项的调用,例如通过记录到文件系统或数据库(或以某种方式将 Moq 编组回 Se 单元测试)。

所以这是一个想法:

  • 确保 WebForms 对存储库依赖项的访问通过接口分离,然后使用服务定位器(1) 获取存储库依赖项的实例以供 WebForm 使用(大多数 IoC 容器同时支持 DI 和服务定位器, 例如 Unity).
  • 将 BootStrap 配置(例如 Unity RegisterInstance / RegisterType)移动到配置 (2) 中。这样你就可以替换你的实际存储库,而无需编辑 IoC bootstrap 代码,例如在 Global.asax 中切换真假存储库。
  • 在单独的程序集中创建一个存根/模拟存储库(如果您使用了 Moq,您可能需要为创建 Moq 的 IoC 提供一个工厂,并且 returns mock.Object ),它将每次调用、参数和时间戳记录到数据库中。
  • 将此程序集复制到您的 Dev Web 服务器,并编辑 IoC 配置以重定向 IRepository 接口以指向您的假存储库。
  • 进行 Selenium 测试。每次操作后,您需要查询验证数据库以断言正确的调用次数。您还需要在每次测试之前/之后进行清理。

(1) 在大多数情况下,Dependency Injection 应该比 Service Locator 更受青睐,但是 (2) 同样,这不是最佳实践,因为可能会失去编译时安全性。然而,IoC 通常有一个 "Validate" 配置机制,它至少可以部分弥补这一点。

您可以考虑将表示层从 WebForms 转移到 ASP.Net MVC,其中依赖注入和单元测试是第一个 class 公民,并且可以访问 Moq 验证 ;)