2011-07-15 30 views
6

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

+0

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? –

+0

Không, tạo một phần giả mạo đối tượng A. –

+0

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

Trả lời

1

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.

+0

[Chương 3 của Osherove đang trực tuyến] (http://www.manning.com/osherove/SampleChapter3.pdf) (PDF) –

3

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.

+0

+1 - đó là một cuốn sách tuyệt vời! – TrueWill

0

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".

1

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.)

2

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.

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