Có lý do nào khiến bạn không nên tạo giả mạo một phần của đối tượng hay chỉ giả một phương pháp trên đối tượng mà bạn đang thử nghiệm để kiểm tra phương pháp khác không? Điều này có thể hữu ích để giúp bạn không tạo ra một đối tượng giả lập hoàn toàn mới, hoặc khi có một sự phụ thuộc bên ngoài trong phương thức bạn đang giả mạo mà bạn không thể loại bỏ một cách hợp lý và muốn tránh khỏi tất cả các thử nghiệm đơn vị khác?Giả mạo một phương pháp của đối tượng dưới thử nghiệm
Trả lời
Các Extract và Override kỹ thuật được mô tả trong Chương 3 của Roy Osherove của The Art of Unit Testing dường như là một cách để phần giả của lớp dưới kiểm tra (tr. 71-77). Osherove không giải quyết những lo ngại nêu ra trong một số câu trả lời khác cho câu hỏi này.
Ngoài ra, Michael Feathers thảo luận về điều này trong Làm việc hiệu quả với Mã kế thừa. Ông điều khoản lớp kết quả là một lớp con kiểm tra (227) và kỹ thuật Lớp con và phương pháp ghi đè (401). Bây giờ, được cấp, Feathers không đưa ra một giải trình các kỹ thuật nguyên sơ được đề xuất trên mã mới. Nhưng ông vẫn cho nó điều trị nghiêm trọng như một kỹ thuật hữu ích tiềm năng.
Tôi cũng đã hỏi giáo sư máy tính cũ của tôi về việc này. Anh ấy được đọc và hiện đang làm việc toàn thời gian trong ngành công nghiệp phần mềm, nơi anh ấy đã tiến bộ nhanh chóng. Anh ta nói rằng kỹ thuật này chắc chắn có một ứng dụng tốt, và có vài chục lớp trong codebase tại công ty của anh ta đang được thử nghiệm theo cách này. Anh ấy nói rằng, giống như bất kỳ kỹ thuật nào, nó có thể bị lạm dụng.
Tôi ban đầu đã viết câu hỏi khi tôi còn mới để kiểm tra đơn vị và biết bên cạnh không có gì về tiêm phụ thuộc. Bây giờ, sau khi một số kinh nghiệm với cả hai, tôi sẽ thêm rằng sự cần thiết phải sử dụng kỹ thuật thử nghiệm này có thể là một mùi. Nó có thể là một dấu hiệu cần phải làm lại cách tiếp cận của bạn với các phụ thuộc. Nếu phương pháp cần được giả mạo là phương thức được kế thừa từ một lớp cơ sở, điều đó có nghĩa là bạn cần phải nghiêm túc xem xét "thành phần ưu tiên hơn thừa kế". Bạn nên tiêm phụ thuộc của bạn hơn là kế thừa chúng.
[Chương 3 của Osherove đang trực tuyến] (http://www.manning.com/osherove/SampleChapter3.pdf) (PDF) –
Các đối tượng bạn muốn làm điều này vì đang cố gắng làm quá nhiều thứ. Đặc biệt, nếu bạn có một phụ thuộc bên ngoài, bạn thường sẽ tạo một đối tượng để cô lập sự phụ thuộc đó. Mẫu façade là một ví dụ về điều này. Nếu đối tượng của bạn không được thiết kế với khả năng kiểm tra trong tâm trí bạn có thể phải làm một số tái cấu trúc. Hãy xem Michael Feathers' PDF on working with legacy code (PDF). Ông cũng có một cuốn sách bằng cùng một tiêu đề mà đi vào chi tiết hơn.
+1 - đó là một cuốn sách tuyệt vời! – TrueWill
Có một số gói thực sự tốt đẹp để tạo điều kiện cho loại công cụ này. Ví dụ, từ Mockito docs:
//You can mock concrete classes, not only interfaces
LinkedList mockedList = mock(LinkedList.class);
//stubbing
when(mockedList.get(0)).thenReturn("first");
hiện một số kỳ diệu thực sự đó là khó có thể tin lúc đầu. Khi bạn gọi
String firstMember = mockedList.get(0);
bạn sẽ quay lại "đầu tiên", vì những gì bạn đã nói trong câu "khi".
Nếu phương pháp bạn muốn giả mạo là ảo (như trong, không tĩnh và không phải cuối cùng), thì bạn có thể phân lớp đối tượng trong thử nghiệm, ghi đè phương thức trong lớp con và thực hiện phân lớp trong thử nghiệm. Không yêu cầu thư viện đối tượng giả.
(Lý tưởng nhất là bạn nên xem xét tái cấu trúc, đây không phải là một giải pháp lâu dài tuyệt vời. Nhưng đó là một cách để có được mã di sản được kiểm tra, do đó bạn có thể bắt đầu quá trình sắp xếp dễ dàng hơn.)
Nó là một ý tưởng rất xấu để giả/một phần giả mạo của một lớp để kiểm tra một lớp khác.
Thực hiện việc này, bạn không kiểm tra mã thực sự thực hiện trong các điều kiện thử nghiệm dẫn đến kết quả thử nghiệm không đáng tin cậy.
Nó cũng làm tăng gánh nặng bảo trì của phần giả của lớp học. Nếu điều này có hiệu lực đối với toàn bộ chương trình thử nghiệm, việc triển khai giả cũng làm cho các thử nghiệm khác trên phương pháp giả khó hơn.
Bạn cần phải tự hỏi tại sao bạn cần giả mạo phần được thử nghiệm.
Nếu đó là vì phương pháp đang truy cập tệp hoặc cơ sở dữ liệu, thì bạn nên xác định giao diện và chuyển giao một thể hiện của giao diện đó cho hàm tạo hoặc phương thức lớp. Điều này cho phép bạn kiểm tra các kịch bản khác nhau trong cùng một ứng dụng thử nghiệm.
Nếu đó là vì bạn đang sử dụng đĩa đơn, bạn nên suy nghĩ lại về thiết kế của mình để làm cho nó dễ kiểm tra hơn: loại bỏ những người độc thân sẽ loại bỏ các phụ thuộc ngầm định và những cơn ác mộng về bảo trì.
Nếu bạn đang sử dụng các phương pháp tĩnh/chức năng tự do để truy cập dữ liệu trong sổ đăng ký hoặc tệp cài đặt, bạn nên thực sự di chuyển ra khỏi hàm dưới kiểm tra và chuyển dữ liệu dưới dạng tham số hoặc cung cấp giao diện nhà cung cấp cài đặt. Điều này sẽ làm cho mã linh hoạt hơn và mạnh mẽ hơn.
Nếu nó là để phá vỡ sự phụ thuộc cho mục đích thử nghiệm (ví dụ:giả mạo một phương thức vectơ để kiểm tra một phương thức trong một lớp ma trận), bạn không nên giả mạo điều đó - bạn nên xử lý mã đang được kiểm tra như những gì được định nghĩa bởi lớp được kiểm tra bởi giao diện công cộng của nó: phương thức; tiền điều kiện, hậu điều kiện, bất biến, tài liệu, thông số và đặc điểm ngoại lệ.
Bạn có thể sử dụng kiến thức về chi tiết triển khai để kiểm tra các trường hợp cạnh đặc biệt, nhưng kích hoạt các trường hợp thông qua API chính, không phải bằng cách giả mạo chi tiết triển khai.
Ví dụ: giả sử bạn giả mạo std :: vector :: at() nhưng thay vào đó việc triển khai được chuyển sang sử dụng toán tử []. Thử nghiệm của bạn sẽ bị phá vỡ hoặc âm thầm trôi qua.
- 1. Giả mạo một phương pháp chung FakeItEasy
- 2. làm thế nào để thử một phương pháp trong một đối tượng khi thử nghiệm một phương pháp trong cùng một đối tượng
- 3. Đối tượng giả vs Cơ sở dữ liệu thử nghiệm
- 4. Phương pháp thử nghiệm
- 5. Phương pháp thiết lập thử nghiệm Nunit với đối số
- 6. có thể giả lập/giả mạo một phương pháp mở rộng không?
- 7. đơn vị thử nghiệm một phương pháp nhà máy
- 8. Điểm cuối EC2 giả để thử nghiệm
- 9. Làm cách nào để giả lập/giả mạo đối tượng phiên trong biểu mẫu Web ASP.Net?
- 10. Giả mạo cơ sở dữ liệu SQLite trong khi thử nghiệm Hoạt động với Robolectric
- 11. Cách chạy phương pháp thử nghiệm hoặc lớp học dưới dạng Thử nghiệm Android trong Android Studio
- 12. đơn vị thử nghiệm một phương thức trả về một đối tượng không tầm thường
- 13. Sử dụng các đối tượng giả ngoài thử nghiệm, thực hành không tốt?
- 14. Hệ thống tệp giả cho thử nghiệm đơn vị Perl
- 15. cấu hình giả trong các thử nghiệm của Grails
- 16. Giả lập một phương thức trong cùng một lớp đang được thử nghiệm
- 17. Đơn vị thử nghiệm phương pháp điều khiển của tôi kết quả trong một ViewName trống?
- 18. Đơn vị thử nghiệm một phương pháp điều khiển?
- 19. Chạy một phương pháp thử nghiệm duy nhất
- 20. Moq: đơn vị thử nghiệm một phương pháp dựa trên HttpContext
- 21. Thử nghiệm đơn vị Các phương pháp Spring @Around AOP
- 22. Phương pháp riêng thử nghiệm đơn vị: Mẫu mặt tiền
- 23. Có thể giả mạo/giả mạo $ _SERVER ['SERVER_NAME'] không?
- 24. JUnit 4: Thiết lập mọi thứ trong một bộ thử trước khi chạy thử nghiệm (như phương pháp @BeforeClass của thử nghiệm, chỉ dành cho bộ thử nghiệm)
- 25. Làm thế nào để bạn giả lập một phương pháp tĩnh của một đối tượng miền trong Grails?
- 26. Khi thử nghiệm với rspec, nơi để đặt phổ biến "phương pháp thử nghiệm tiện ích"?
- 27. Perl luồng của phương pháp đối tượng
- 28. Thử nghiệm phương pháp thay vì thử nghiệm toàn bộ tệp trong Netbeans w/JUnit
- 29. Mockito bỏ qua phương pháp tĩnh để thử nghiệm
- 30. Tạo dữ liệu giả cho thử nghiệm đơn vị
Xin lỗi, chỉ cần làm rõ - bạn có đối tượng A đang thử nghiệm và đối tượng A dựa vào đối tượng B để bạn muốn tạo một phần giả của đối tượng B? –
Không, tạo một phần giả mạo đối tượng A. –
Bạn cần [Powermock] (http://code.google.com/p/powermock/). Với điều này bạn có thể giả lập các phương thức tĩnh, các phương thức riêng, các hàm tạo, bạn thực sự có thể thực hiện bất kỳ phép thuật nào vì nó tinh chỉnh mã byte của các lớp. Đây chính xác là những gì bạn cần. – edutesoy