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

rem*_*mio 13 .net c# aop unit-testing postsharp

在询问了关于使用PostSharp实现方面的这个问题之后,我想到我将来可能不得不更新这方面的代码,并且我不想承担之后破坏所有内容的风险.

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

我的第一个问题是:

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

我希望答案是"是",但如果没有,我希望得到其他建议.

然后,如果是这样,

如何实现PostSharp方面的单元测试?

ntz*_*lis 10

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

但是,您必须将其分为两部分:

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

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

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

在该注释中,您还应该使用编译时验证,这也可以防止您以错误的方式使用属性.有时需要测试使用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);
    }
}
Run Code Online (Sandbox Code Playgroud)

你可能会问为什么TraceService和另外一个TraceArgumentService:

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