c# - 如何对 PostSharp 方面进行单元测试?

标签 c# .net unit-testing aop postsharp

问这个之后question关于用 PostSharp 实现一个方面,我想到以后我可能必须更新这个方面的代码,我不想冒之后破坏一切的风险。

所以,我开始考虑单元测试。

我的第一个问题是:

Is it relevant to think about unit testing an aspect?

我希望答案是"is",但如果不是,我希望得到其他建议。

然后,如果是这样,

How to implement unit testing for PostSharp aspects?

最佳答案

是的,它对单元测试方面当然有意义,因为它们代表功能,而且由于您在多个地方使用它,因此测试它就更加重要了。

但是你必须把它分成两部分:

  1. 测试实际方面的功能
  2. 测试用于实际执行方面功能的上下文提取是否正常工作

对于第一部分,如果您已经将实际功能与正确执行方面功能的属性分离,那么创建单元测试应该与单元测试普通代码没有什么不同。

对于第二部分,您还需要解耦上下文的提取,这似乎有点过分,但如果您想要正确地对其进行单元测试,恐怕您将需要这样做。

关于这一点,您还应该使用编译时验证,这也可以防止您以错误的方式使用属性。有时有必要测试某些您无法用属性语法描述的条件,然后编译时验证开始发挥作用。这对我来说是一笔巨大的财富,显着减少了 PostSharp 方面的调试 session 数量,请参阅:
http://www.sharpcrafters.com/postsharp/robustness

这是一些非常基本的示例代码,没有 DI 什么都没有,只是为了说明如何拆分:

public sealed class TraceAttribute : OnMethodBoundaryAspect
{
    private readonly string category;
    private TraceArgumentService argumentService;
    private TraceService traceService;

    public string Category { get { return category; } }

    public TraceAttribute(string category)
    {
        this.category = category;
    }

    public override void RuntimeInitialize(System.Reflection.MethodBase method)
    {
        base.RuntimeInitialize(method);
        this.argumentService = new TraceArgumentService();
        this.traceService = new TraceService();
    }


    public override void OnEntry(MethodExecutionArgs args)
    {                
        traceService.Write(
            argumentService.GetDeclaringTypeName(args),
            argumentService.GetMethodName(args),
            category);

    }
}

public class TraceArgumentService
{
    public string GetDeclaringTypeName(MethodExecutionArgs args)
    {
        return args.Method.DeclaringType.Name;
    }

    public string GetMethodName(MethodExecutionArgs args)
    {
        return args.Method.Name;
    }
}

public class TraceService
{
    public void Write(string declaringTypeName, string methodName, string category)
    {
        Trace.WriteLine(string.Format("Entering {0}.{1}.",
            declaringTypeName, methodName), category);
    }
}

您可能会问为什么 TraceService 和一个单独的 TraceArgumentService:

  • Tracing 逻辑应该独立于 PostSharp,因此它不应该知道 MethodExecutionArgs
  • MethodExecutionArgs 中提取参数不是 Tracing 的一部分,它与方面更相关。由于您希望能够对其进行测试,因此需要以某种方式将其分离。

关于c# - 如何对 PostSharp 方面进行单元测试?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9737431/

相关文章:

android - robotium,如何测试 ListView

C# 宏样式泛型

c# - 变量如何寻址RAM?

c# - 瑞典 SSN 正则表达式拒绝特定年龄以下的用户

.net - 将 .NET 表单设置为 HWND 的父级

android - 在 `runBlockingTest` 测试 Room 的事务查询

javascript - 使用 mocha 模拟 Nodejs 中的函数

c# - 就数据库表设计、估算表提出建议

c# - 从 .net 的角度来看,exe 和 dll 之间有什么特别的区别吗?

.net - 如何在强类型列表中搜索字符串?