2012-03-07 9 views
5

giả sử tôi có một số OrderProcessor s, mỗi người trong số họ xử lý một đơn đặt hàng một chút khác nhau.
Quyết định về những OrderProcessor sử dụng được thực hiện theo các thuộc tính của đối tượng Order, và được thực hiện bằng một phương pháp nhà máy, như vậy:đơn vị thử nghiệm một phương pháp nhà máy

public IOrderProcessor CreateOrderProcessor(IOrdersRepository repository, Order order, DiscountPercentages discountPercentages) 
{ 
    if (order.Amount > 5 && order.Unit.Price < 8) 
    { 
     return new DiscountOrderProcessor(repository, order, discountPercentages.FullDiscountPercentage); 
    } 

    if (order.Amount < 5) 
    { 
     // Offer a more modest discount 
     return new DiscountOrderProcessor(repository, order, discountPercentages.ModestDiscountPercentage); 
    } 

    return new OutrageousPriceOrderProcessor(repository, order); 
} 

Bây giờ, vấn đề của tôi là tôi muốn xác minh rằng trả lại OrderProcessor đã nhận được thông số chính xác (ví dụ: tỷ lệ phần trăm giảm giá chính xác).
Tuy nhiên, các thuộc tính đó không được công khai trên các đối tượng OrderProcessor.

Bạn đề xuất tôi xử lý tình huống này như thế nào?

Giải pháp duy nhất tôi đã có thể đưa ra được làm tài sản tỷ lệ chiết khấu của OrderProcessor s công cộng, nhưng nó có vẻ như một overkill để làm điều đó chỉ với mục đích kiểm tra đơn vị ...

Trả lời

3

Một cách xung quanh việc này là thay đổi các trường bạn muốn kiểm tra nội bộ thay vì riêng tư và sau đó đặt nội bộ của dự án hiển thị cho dự án thử nghiệm. Bạn có thể đọc về đây này: http://msdn.microsoft.com/en-us/library/system.runtime.compilerservices.internalsvisibletoattribute.aspx

Bạn sẽ làm một cái gì đó như thế này trong AssemblyInfo.cs tập tin của bạn:

[assembly:InternalsVisibleTo("Orders.Tests")] 

Mặc dù bạn có thể tranh luận rằng các xét nghiệm đơn vị của bạn không nên nhất thiết phải quan tâm đến các lĩnh vực riêng tư của bạn lớp học. Có lẽ tốt hơn là truyền các giá trị cho phương thức factory và viết test unit cho kết quả mong đợi khi một số method (giả định Calculate() hoặc một cái gì đó tương tự) được gọi trên giao diện.

Hoặc cách tiếp cận khác là kiểm tra đơn vị các loại bê tông (DiscountOrderProcessor, v.v.) và xác nhận giá trị trả về của chúng từ các phương thức/thuộc tính công khai. Sau đó viết các bài kiểm tra đơn vị cho phương thức factory mà nó trả về đúng kiểu triển khai giao diện chính xác.

Đây là những cách tiếp cận tôi thường thực hiện khi viết mã tương tự, tuy nhiên có nhiều cách khác nhau để giải quyết vấn đề như thế này. Tôi sẽ khuyên bạn nên tìm ra nơi bạn sẽ nhận được giá trị nhất trong các bài kiểm tra đơn vị và viết theo đó.

1

Nếu tỷ lệ chiết khấu không công khai, sau đó nó không phải là một phần của hợp đồng IOrderProcessor và do đó không cần phải được xác minh. Chỉ cần có một tập hợp các bài kiểm tra đơn vị cho DiscountOrderProcessor để xác minh nó tính toán đúng mức giảm giá của bạn dựa trên phần trăm giảm giá được truyền qua thông qua nhà xây dựng.

+1

Trong khi điều này là tốt và có vẻ hợp lý khi muốn biết rằng tỷ lệ chiết khấu chính xác đang được sử dụng, nếu không ai đó có thể thay đổi mã để làm cho cả hai đường dẫn trở lại 'discountPercentages.FullDiscountPercentage' và không ai biết, và tất cả những người bất ngờ sẽ bắt đầu nhận được giảm giá đầy đủ chứ không phải là mức khiêm tốn –

+0

Ok, hãy tạo ra DiscountOrderProcessor trong một phương thức ảo và đảm bảo nó được gọi với các tham số thích hợp dựa trên logic nhà máy của bạn. – PatrickSteele

+0

Tôi sẽ phải đồng ý với Patrick. Nghe có vẻ như bạn đang mạo hiểm ra khỏi thử nghiệm đơn vị vào thử nghiệm tích hợp (đó là quan trọng là tốt). Thử nghiệm đơn vị là cho một đơn vị logic và mỗi bộ xử lý đơn hàng phải có các thử nghiệm đơn vị riêng của nó. –

0

Bạn có một vài lựa chọn như tôi thấy. bạn có thể tạo chuyên môn của DiscountOrderProcessor:

public class FullDiscountOrderProcessor : DiscountOrderProcessor 
{ 
    public FullDiscountOrderProcessor(IOrdersRepository repository, Order order):base(repository,order,discountPercentages.FullDiscountPercentage) 
    {} 
} 

public class ModestDiscountOrderProcessor : DiscountOrderProcessor 
{ 
    public ModestDiscountOrderProcessor (IOrdersRepository repository, Order order):base(repository,order,discountPercentages.ModestDiscountPercentage) 
    {} 
} 

và kiểm tra loại trả về đúng.

bạn có thể vượt qua trong một nhà máy để tạo DiscountOrderProcessor chỉ mất một số tiền, sau đó bạn có thể kiểm tra điều này đã được gọi với các thông số chính xác.

Bạn có thể cung cấp phương pháp ảo để tạo DiscountOrderProcessor và kiểm tra được gọi với thông số chính xác.

Tôi rất thích tùy chọn đầu tiên, nhưng tất cả các phương pháp này đều gặp vấn đề mà cuối cùng bạn không thể kiểm tra giá trị thực và vì vậy ai đó có thể thay đổi số tiền chiết khấu của bạn và bạn sẽ không biết. Ngay cả khi bạn sử dụng cách tiếp cận đầu tiên bạn sẽ không thể kiểm tra giá trị được áp dụng cho FullDiscountOrderProcessor là gì.

Bạn cần có cách nọ cách kia để kiểm tra giá trị thực tế mà lá bạn với:

bạn có thể làm cho các tài sản công cộng (hoặc nội bộ - sử dụng InternalsVisibleTo) để bạn có thể thẩm vấn họ.

bạn có thể lấy đối tượng được trả về và kiểm tra xem đối tượng đó có áp dụng chính xác chiết khấu cho một số đối tượng mà bạn chuyển vào đối tượng đó hay không.

Cá nhân tôi muốn tạo các thuộc tính bên trong, nhưng nó phụ thuộc vào cách các đối tượng tương tác và nếu truyền một đối tượng giả vào bộ xử lý đơn hàng giảm giá và xác minh rằng nó được thực hiện một cách chính xác thì đơn giản thì đây có thể là giải pháp tốt hơn.