2012-03-16 29 views
13

Sau khi yêu cầu question về việc triển khai một khía cạnh với PostSharp, tôi nghĩ rằng tôi có thể phải cập nhật mã của khía cạnh này trong tương lai và rằng tôi không muốn mạo hiểm phá vỡ mọi thứ sau đó.Làm thế nào để đơn vị kiểm tra các khía cạnh PostSharp?

Vì vậy, tôi bắt đầu nghĩ về thử nghiệm đơn vị.

câu hỏi đầu tiên của tôi là:

Có liên quan đến suy nghĩ về đơn vị kiểm nghiệm một khía cạnh?

Tôi muốn câu trả lời là "có", nhưng nếu không, tôi mong nhận được các lời khuyên khác.

Và sau đó, nếu như vậy,

Làm thế nào để thực hiện kiểm tra đơn vị cho các khía cạnh PostSharp?

Trả lời

10

Có chắc chắn có ý nghĩa đối với các khía cạnh kiểm tra đơn vị, vì chúng thể hiện chức năng và vì bạn đang sử dụng nó ở nhiều nơi, việc kiểm tra nó thậm chí còn quan trọng hơn.

Tuy nhiên bạn phải chia thành hai phần:

  1. Kiểm tra chức năng khía cạnh thực tế
  2. Testing liệu khai thác bối cảnh hoạt động đúng được sử dụng để thực thi các chức năng khía cạnh

Đối với phần đầu tiên, nếu bạn đã tách riêng chức năng thực tế khỏi thuộc tính thực thi chức năng khía cạnh đúng cách, việc tạo các kiểm tra đơn vị sẽ không khác với mã kiểm tra đơn vị bình thường.

Đối với phần thứ hai, bạn cần phải tách rời ngữ cảnh, điều này có vẻ quá mức cần thiết nhưng nếu bạn đơn vị kiểm tra nó đúng cách, bạn sẽ cần phải làm điều đó tôi sợ.

Trên lưu ý đó, bạn cũng nên sử dụng xác thực thời gian biên dịch, điều này cũng có thể ngăn bạn sử dụng các thuộc tính theo cách sai. Đôi khi cần phải kiểm tra các điều kiện nhất định mà bạn không thể mô tả bằng cú pháp Thuộc tính, sau đó biên dịch xác nhận thời gian đi vào hoạt động. Đây là một tài sản lớn đối với tôi và giảm số lượng phiên gỡ rối liên quan đến khía cạnh PostSharp đáng kể, xem:
http://www.sharpcrafters.com/postsharp/robustness

Dưới đây là một số mẫu mã rất cơ bản, không DI gì cả, chỉ để minh họa làm thế nào để chia thứ lên:

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); 
    } 
} 

Bạn có thể hỏi tại sao TraceService và riêng biệt TraceArgumentService:

  • Logic Tracing nên được độc lập từ PostSharp, do đó nó SHO uld không biết về MethodExecutionArgs.
  • Trích xuất đối số từ MethodExecutionArgs không phải là một phần của Truy tìm, nó có liên quan nhiều hơn đến khía cạnh. Vì bạn muốn có thể kiểm tra nó, bạn cần phải bằng cách nào đó tách nó ra.
+0

Tôi hoàn toàn đồng ý với "phần đầu" của bạn. Về "phần thứ hai" của bạn, tôi đang tìm mẫu mã để hiểu "nó trông như thế nào" vì đây là điểm mấu chốt trong câu hỏi của tôi. Tôi sẽ điều tra xác nhận thời gian biên dịch theo đề xuất của bạn. – remio

+1

@remio Tôi đã cập nhật câu trả lời của mình với một ví dụ về cách tách riêng nhiệm vụ khác nhau để làm cho chúng có thể kiểm tra được – ntziolis

+0

Tôi hiểu. Tách là chìa khóa. Cảm ơn rất nhiều cho ví dụ rõ ràng của bạn. – remio

Các vấn đề liên quan