2013-02-20 24 views
9

Về thử nghiệm đơn vị, tôi được dạy rằng mã sản xuất không nên có mã liên quan đến thử nghiệm trong đó.Các giao diện thực hiện đơn lẻ có dành cho đơn vị thử nghiệm một antipattern không?

Vâng, tôi cảm thấy như tôi đang phá vỡ quy tắc đó mỗi lần tôi thử kiểm tra đơn vị.

Tôi có một lớp học trong nội bộ của mình, Xyzzy. Tôi muốn phụ thuộc tiêm nó vào một lớp khác và sau đó stub nó để tôi có thể kiểm tra rằng các lớp khác trong sự cô lập, vì vậy tôi làm cho một giao diện, IXyzzy. Rất tiếc, bây giờ tôi có mã sản xuất thực sự chỉ ở đó để thử nghiệm. Thậm chí tệ hơn, tôi đã đi ngược lại giao diện là gì (mô tả những gì một người thực hiện có thể làm, không phải là những gì nó ). Giao diện công cộng của Xyzzy và IXyzzy hoàn toàn giống nhau và không ai khác (ngoại trừ các nhánh) thực hiện IXyzzy.

Điều đó có vẻ như là một điều xấu đối với tôi.

Tôi có thể tạo lớp cơ sở trừu tượng hoặc tạo tất cả các phương pháp công khai mà tôi muốn thử nghiệm trên Xyzzy Overridable/virtual, nhưng điều đó cũng không đúng vì Xyzzy không được thiết kế để thừa kế và từ quan điểm YAGNI được thừa kế từ.

Việc tạo giao diện người triển khai duy nhất chỉ nhằm mục đích thử nghiệm chống mẫu? Có lựa chọn thay thế tốt hơn?

Trả lời

7

Không chỉ có mã để thử nghiệm. Điều này thực sự bình thường, giống như mã sản xuất chứa các tính năng được tạo ra chỉ để gỡ lỗi và giám sát sản xuất. Không có lý do rõ ràng điều này nên không được phép. Mã nên hỗ trợ tất cả các khía cạnh của vòng đời của ứng dụng. Thử nghiệm chỉ là một phần của vòng đời.

Trong ý nghĩa đó, cách tiếp cận của bạn bằng cách sử dụng giao diện là chính xác. Nếu bạn làm cho phần còn lại của ứng dụng sản xuất cũng sử dụng giao diện (và không phải là lớp bê tông mặc dù chỉ có một) đó là âm thanh kiến ​​trúc.

Tôi đã loại đi ngược lại những gì Giao diện (mô tả những gì một người thực hiện thể làm được, nó không phải là những gì)

tôi đã không nhận được quan điểm của bạn ở đây vì giao diện không mô tả những gì đối tượng có thể làm. Chỉ có một việc thực hiện cụ thể (sản xuất) không phá hủy tài sản này.

Nếu bạn nghĩ về điều đó, mỗi lớp có một "giao diện" theo ý nghĩa lỏng lẻo của từ: chữ ký công khai của tất cả các phương thức cho thấy một giao diện mà lớp đó hỗ trợ bên ngoài. Cho dù giao diện .NET có được triển khai hay không chỉ là một chi tiết. Lớp học vẫn hứa hẹn cùng với bên ngoài.

+1

Rất đúng, rất nhiều giao diện của tôi, ví dụ: 'IRequestor', mô tả những gì nó làm;) –

3

Theo kinh nghiệm của tôi, điều này khá điển hình trong phát triển .NET, xuất phát từ thực tế là ghi đè phương pháp là trên cơ sở chọn tham gia; nếu bạn muốn giả lập một phụ thuộc, bạn cần một giao diện hoặc một đối tượng có các phương thức đều là ảo.

Trong một ngôn ngữ như Java, ở đó mọi phương thức đều có thể ghi đè lên các giao diện thực hiện đơn lẻ thực sự là một mẫu giả, và các nhà phát triển tốt sẽ gọi nó ra.

Tiếp tục làm những gì bạn đang làm - bất cứ điều gì tội lỗi bạn đang cam kết, theo quan điểm của tôi, được cân nhắc nhiều hơn bởi lợi ích của thử nghiệm đơn vị của bạn!

+2

Đồng ý về lợi ích của việc kiểm thử đơn vị;) Bài viết thú vị về lý do tại sao C# không có các phương thức mặc định ảo theo mặc định: http://geekswithblogs.net/madhawa/archive /2006/09/17/91418.aspx –

+0

Liên kết thú vị, cảm ơn! – Ben

2

Có, đó là hình mẫu chống.Một mẫu sẽ là "một giải pháp cho một vấn đề chung trong một ngữ cảnh nhất định". Nhưng trong trường hợp này, những gì chúng tôi có là làm việc xung quanh, không phải là giải pháp.

Các vấn đề trong câu hỏi là sự cần thiết phải cách ly một đơn vị được kiểm tra từ (một số) phụ thuộc của nó, do đó việc thực hiện những người phụ thuộc không phải được xem xét khi viết các bài kiểm tra đơn vị. Giải pháp chung và đúng cho vấn đề này được gọi là "chế nhạo", nơi mà người viết thử nghiệm có thể chỉ định bất kỳ hành vi nào là cần thiết từ các phụ thuộc giả lập.

Ngược lại, buộc nhà phát triển tạo các giao diện riêng biệt không cần thiết hoặc khai báo các phương thức là virtual, chỉ là một công việc xung quanh để không thể tách biệt một đơn vị khỏi những người khác.

Đối với .NET, có một số công cụ chế nhạo cung cấp khả năng cách ly này, cụ thể là TypeMock Isolator, JustMock và MS Fakes. Các ngôn ngữ/nền tảng khác (bao gồm Java, Ruby và Python) có các công cụ riêng có sức mạnh biểu đạt tương tự.

+1

Có một câu hỏi SO tốt mà nói về phần cuối cùng của câu trả lời của bạn: [Có sử dụng giao diện Soley để tạo thuận lợi cho việc gửi bài và thử nghiệm trong bài kiểm tra đơn vị đã lỗi thời?] (Http://stackoverflow.com/q/3869002/945456) –