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

时间:2012-03-16 12:41:40

标签: c# .net unit-testing aop postsharp

在询问question关于使用PostSharp实现方面之后,我想到我将来可能不得不更新这方面的代码,并且我不想承担破坏的风险之后的一切。

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

我的第一个问题是:

  

考虑单元测试方面是否相关?

我希望答案是“是”,但如果没有,我希望得到其他建议。

然后,如果是的话,

  

如何为PostSharp方面实施单元测试?

2 个答案:

答案 0 :(得分:10)

是的,它确实对单元测试方面有意义,因为它们代表功能,因为你在不止一个地方使用它,所以测试它更为重要。

但是你必须将它分为两​​部分:

  1. 测试实际方面功能
  2. 测试上下文提取是否正常用于实际执行方面功能
  3. 对于第一部分,如果您已将实际功能与正确执行方面功能的属性分离,则创建单元测试应该与单元测试普通代码没有什么不同。

    对于第二部分,你需要解除上下文的提取,这看起来有点矫枉过正,但是如果你想对它进行单元测试,那么你恐怕需要它。

    在该注释中,您还应该使用编译时验证,这也可以防止您以错误的方式使用属性。有时需要测试使用Attribute语法无法描述的某些条件,然后编译时验证开始起作用。这对我来说是一笔巨大的财富,并且显着减少了有关PostSharp方面的调试会话数量,请参阅:
    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

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

答案 1 :(得分:1)