c# - 如何通过 C# TestFrameworks 使用 DI 框架中的 AOP? (不适用于被测项目)

标签 c# dependency-injection nunit aop mbunit

我提前为糟糕的标题道歉 - 欢迎提出建议!

我一直在阅读有关 DI 和 AOP 的文章,我认为我掌握了基础知识;至少对于添加日志记录的规范示例而言。

我想将其应用于我们在 NUnit 中创建的测试用例,例如能够为所有测试用例方法和它们调用的任何“辅助方法”自动添加进入/退出日志记录。 (而且我不依赖于 NUnit - 如果在其他框架中更容易,请告诉我。)

注意-这与被测对象无关;我想将这些技术应用到测试用例本身。

很清楚如何使用 PostSharp 来做到这一点- 这是他们的 First example.但是,我不想仅仅为了这个实验而将他们的许可处理添加到我们的项目中。

我发现的所有其他关于 C# 的 AOP 的引用资料都是基于 IoC 容器实现提供的(动态)拦截器,例如 CaSTLeWindsor、Unity、Spring.Net,......在这种情况下它们都有一个共同的问题:您需要一段设置代码来为要添加拦截器的对象创建代理。 (我最初认为这段代码也必须创建一个 IoC 容器,但我发现我错了。)

但我看不出这个设置代码将用于 nUnit 测试用例。

我想到的选项,以及它们的问题:

  1. 让 testfixture 类构造函数为其自身创建一个代理。不会工作,由于递归(消费者要求事物,事物试图将代理返回给事物,代理试图创建事物......来自阅读 this StackOverflow question )
  2. 推出我自己的基于反射的魔法(这对我来说是一项艰巨的任务)
    1. 让构造函数包装 testfixture 类中的所有方法并返回这个“包装”对象(不确定构造函数是否可以这样做)
    2. 在 testfixture 上使用静态构造函数来实现这个魔法(假设您可以动态地包装类的方法。)
    3. 使用模块 cctor(通过 Einar Egilsson's InjectModuleInitializer)在模块级别做一些事情,并用日志记录包装所有类中的所有方法。
  3. 最简单的:某种用于实例化测试用例的工厂(不是测试参数),我可以从中使用其中一个 IoC 代理生成器
    1. 对于 nUnit:我能找到的唯一方法是创建一个 custom AddIn .优势 - 可能不会破坏与 ReSharper 的集成。缺点——部署到所有开发机器上,尤其是在更新 NUnit 时。 nUnit 是否有其他方法可以做到这一点?
    2. 对于 MbUnit:看起来像 treats testcases as first class values ,这是直截了当的。优点:易于部署给所有开发人员。缺点:测试不会出现在 Resharper 中。旁注:how to handle setup and teardown .

我的选择和结论中是否漏掉了什么?

有没有我错过的更简单的方法?

最佳答案

Aspect Oriented Programming 不仅仅是关于使用动态代理(拦截)或编译后代码编织(PostSharp)。 AOP主要是添加横切关注点。使用动态代理是添加横切关注点的一种方式。代码编织是另一种方法。但还有另一种添加横切关注点的方法,IMO 更好。

与其使用动态代理或代码编织,不如让应用程序的设计引导您。当您使用正确的抽象设计应用程序时,使用装饰器添加横切关注点将很容易。您可以找到使用适当抽象设计的系统示例 herehere .

这些文章描述了如何使用装饰器定义横切关注点。当您以这种方式设计系统时,您可以独立于其余代码测试横切关注点的实现。当使用正确的抽象时,这将很容易。

执行此操作时,无需在单元测试中执行任何特殊操作。无需代码编织,无需在测试中运行 DI 容器来为您构建对象。您可以在没有任何横切关注点的情况下测试您的应用程序逻辑。您可以单独测试每个小部分,然后将所有部分放在您应用程序的 Composition Root 中。 .

关于c# - 如何通过 C# TestFrameworks 使用 DI 框架中的 AOP? (不适用于被测项目),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13462612/

相关文章:

c# - 如何在我的错误日志中使用步骤的名称? NUnit、Specflow、C#

c# - Nunit 3.0 及更高版本中的测试异常

c# - 列表中的 OutOfMemoryException

javascript - 按 foreach Razor 内的日期订购

asp.net-mvc - 如何从 MVC 业务对象中引用 Entity Framework DbContext?

c# - 解决对象的最佳方法是什么?

java - 我应该注入(inject)执行算法所需的对象吗?我应该注入(inject)一切吗?

c# - 在单元测试之前加载 Microsoft.SqlServer.Types 的正确方法是什么

c# - 无法通过 IP 地址连接到 SQL Server Express - c#

c# - SpreadsheetGear CopyFromDataTable 单元格格式