Các phương pháp Riêng tư / Được bảo vệ có nên nằm trong thử nghiệm đơn vị không?


82

Trong phát triển TDD, điều đầu tiên bạn thường làm là tạo giao diện và sau đó bắt đầu viết các bài kiểm tra đơn vị của bạn dựa trên giao diện đó. Khi bạn tiến bộ qua quy trình TDD, bạn sẽ kết thúc việc tạo một lớp triển khai giao diện và sau đó tại một thời điểm nào đó, bài kiểm tra đơn vị của bạn sẽ vượt qua.

Bây giờ câu hỏi của tôi là về các phương thức riêng tư và được bảo vệ mà tôi có thể phải viết trong lớp của mình để hỗ trợ các phương thức / thuộc tính được hiển thị bởi giao diện:

  • Các phương thức private trong lớp có nên kiểm tra đơn vị riêng của chúng không?

  • Các phương thức được bảo vệ trong lớp có nên kiểm tra đơn vị của riêng chúng không?

Suy nghĩ của tôi:

  • Đặc biệt là vì tôi đang viết mã cho các giao diện, tôi không nên lo lắng về các phương thức được bảo vệ / riêng tư vì chúng là hộp đen.

  • Bởi vì tôi đang sử dụng các giao diện, tôi đang viết các bài kiểm tra đơn vị để xác nhận rằng hợp đồng được xác định được thực hiện đúng bởi các lớp khác nhau thực hiện giao diện, vì vậy một lần nữa tôi không nên lo lắng về các phương thức riêng tư / được bảo vệ và chúng nên được thực hiện thông qua các bài kiểm tra đơn vị gọi các phương thức / thuộc tính được xác định bởi giao diện.

  • Nếu phạm vi bảo vệ mã của tôi không cho thấy rằng các phương thức được bảo vệ / riêng tư đang bị tấn công, thì tôi không có các kiểm tra đơn vị phù hợp hoặc tôi có mã không được sử dụng và cần được xóa.


1
Nếu bạn không thực hiện các phương pháp được bảo vệ khỏi các bài kiểm tra của mình, bằng cách ghi đè hoặc bằng cách gọi chúng, tại sao chúng được bảo vệ, thay vì riêng tư? Bằng cách làm cho chúng được bảo vệ, bạn đang đưa ra quyết định có ý thức để hiển thị điểm / chức năng mở rộng. Đối với tôi, nếu bạn đang theo dõi TDD, quyết định này nên được thúc đẩy bởi các bài kiểm tra bạn đang viết.
forsvarir

2
Bạn nên đặt phần về suy nghĩ của riêng bạn trong một câu trả lời riêng. Hãy cho tôi biết khi bạn làm và tôi sẽ ủng hộ.
Keith Pinson


Bạn nói đúng về các bài kiểm tra đơn vị đang hoạt động, tức là những bài kiểm tra được thiết lập để chạy liên tục. Đối với những thứ này, bạn chỉ muốn kiểm tra các giao diện công khai và được bảo vệ. Bạn có thể và có thể hưởng lợi từ việc viết các bài kiểm tra cho các phương pháp riêng tư. Những thử nghiệm đó không nên là một phần của bộ liên tục của bạn, nhưng là một phần để xác minh việc triển khai của bạn có tốt, nó có thể là một công cụ có giá trị cao.
Didier A.

Câu trả lời:


108

Không, tôi không nghĩ đến việc thử nghiệm các phương pháp riêng tư hoặc được bảo vệ. Các phương thức riêng tư và được bảo vệ của một lớp không phải là một phần của giao diện công khai, vì vậy chúng không thể hiện hành vi công khai. Nói chung các phương pháp này được tạo ra bằng cách tái cấu trúc bạn áp dụng sau khi bạn đã làm cho thử nghiệm của mình chuyển sang màu xanh lục.

Vì vậy, các phương pháp riêng tư này được kiểm tra ngầm bởi các bài kiểm tra xác nhận hành vi của giao diện công khai của bạn.

Một lưu ý triết học hơn, hãy nhớ rằng bạn đang kiểm tra hành vi chứ không phải phương pháp. Vì vậy, nếu bạn nghĩ về tập hợp những thứ mà lớp được kiểm tra có thể làm, miễn là bạn có thể kiểm tra và khẳng định rằng lớp hoạt động như mong đợi, cho dù có các phương thức riêng tư (và được bảo vệ) được sử dụng nội bộ bởi lớp để triển khai không hành vi đó là không liên quan. Những phương pháp đó là chi tiết thực hiện của hành vi công cộng.


23
Tôi thích thực tế là bạn đã nói rằng đơn vị kiểm tra, kiểm tra hành vi chứ không phải phương pháp! Điều đó làm rõ mọi thứ rất nhiều.
Raj Rao

1
Tôi đồng ý với @rajah. Đó phải là tuyên bố đầu tiên trong mọi hướng dẫn. Tôi đã tự hỏi làm thế nào để kiểm tra các phương pháp của mình, bây giờ tôi biết tôi không cần phải làm vậy. +1
frostymarvelous

3
Bạn có nói rằng điều này vẫn áp dụng trong trường hợp các lớp cơ sở thực hiện hành vi được bảo vệ mà công chúng được mong đợi sẽ kế thừa và sử dụng không? Khi đó các phương thức được bảo vệ vẫn là một phần của giao diện công khai, phải không?
Nick Udell

1
Nói chung, các mẫu ưu tiên phân tách các mối quan tâm phù hợp hơn với các thử nghiệm đơn vị cô lập trong khi các mẫu thiên về tính đóng gói có các API dễ sử dụng hơn.
尤川豪

3
Điều này không làm rõ trường hợp khả năng hiển thị được bảo vệ. Có vẻ như một phương thức được bảo vệ cũng là một phần của giao diện, thông thường, đó là một điểm mở rộng, được cố ý tạo ra để được bảo vệ như vậy. Tôi muốn nói trong những trường hợp đó, bạn cũng nên kiểm tra đơn vị chúng. Bạn không muốn bất kỳ ai thay đổi mọi thứ trong tương lai và phá vỡ các lớp phụ thuộc vào các điểm mở rộng đó cho hành vi.
Didier A.

45

Tôi không đồng ý với hầu hết các áp phích.

Quy tắc quan trọng nhất là: QUY TẮC LÀM VIỆC CỦA BỘ LUẬT LÝ THUYẾT TRUMPS về công khai / bảo vệ / riêng tư.

Mã của bạn nên được kiểm tra kỹ lưỡng. Nếu bạn có thể đạt được điều đó bằng cách viết các bài kiểm tra cho các phương thức công khai, thực hiện đủ các phương thức được bảo vệ / riêng tư, thì điều đó thật tuyệt.

Nếu bạn không thể, hãy cấu trúc lại để bạn có thể hoặc bẻ cong các quy tắc được bảo vệ / riêng tư.

Có một câu chuyện tuyệt vời về một nhà tâm lý học đã cho trẻ em làm bài kiểm tra. Ông đưa cho mỗi đứa trẻ hai tấm gỗ có gắn một sợi dây ở mỗi đầu và yêu cầu chúng băng qua một căn phòng với chân chạm sàn càng nhanh càng tốt. Tất cả bọn trẻ đều sử dụng những tấm ván như ván trượt nhỏ, đặt một chân lên mỗi tấm ván, giữ chúng bằng dây và trượt trên sàn. Sau đó, ông giao cho họ nhiệm vụ tương tự, nhưng chỉ sử dụng MỘT bảng. Họ xoay / "đi bộ" trên sàn, một chân trên mỗi đầu của bảng duy nhất - và họ NHANH HƠN!

Chỉ vì Java (hoặc bất kỳ ngôn ngữ nào) có một tính năng (riêng tư / bảo vệ / công khai) không nhất thiết có nghĩa là bạn đang viết mã tốt hơn vì bạn sử dụng nó!

Bây giờ, sẽ luôn có cách để tối ưu hóa / giảm thiểu xung đột này. Trong hầu hết các ngôn ngữ, bạn có thể đặt một phương thức được bảo vệ (thay vì công khai) và đặt lớp thử nghiệm trong cùng một gói (hoặc bất cứ thứ gì), và phương thức sẽ có sẵn để thử nghiệm. Có những chú thích có thể giúp ích, như được mô tả bởi các áp phích khác. Bạn có thể sử dụng sự phản chiếu để nhận được các phương thức riêng tư (yuck).

Bối cảnh cũng quan trọng. Nếu bạn đang viết một API để người bên ngoài sử dụng, thì công khai / riêng tư quan trọng hơn. Nếu đó là một dự án nội bộ - ai thực sự quan tâm?

Nhưng vào cuối ngày, hãy nghĩ xem có bao nhiêu lỗi gây ra do thiếu thử nghiệm. Sau đó, so sánh với số lỗi do các phương pháp "hiển thị quá mức" gây ra. Câu trả lời đó sẽ thúc đẩy quyết định của bạn.


3
Nếu một phương pháp là quan trọng và có logic phức tạp, việc khẳng định hành vi của nó là rất hữu ích trong việc ngăn chặn lỗi. Viết một bài kiểm tra đơn vị cho một phương pháp như vậy thậm chí có thể hữu ích khi bạn đang triển khai phương pháp theo kiểu khám phá. Vì vậy, ngay cả khi nó là riêng tư, tôi muốn nói rằng nó đáng để thử nghiệm đơn vị. NHƯNG, và có một vấn đề lớn nhưng bạn phải nhớ rằng các bài kiểm tra là sự ghép nối mã. Nếu bạn viết thử nghiệm cho một phương thức, bạn đang ngăn việc tái cấu trúc.
Didier A.

6
Vì vậy, trước khi bạn bắt đầu viết các bài kiểm tra cho các phương pháp riêng tư, tôi muốn nói rằng hãy luôn suy nghĩ lại thiết kế của bạn. Xem liệu mọi thứ có thể được khái quát hóa và biến thành các phương pháp chức năng thuần túy hay không. Nếu vậy, bạn có thể trích xuất chúng thành cấu trúc của riêng chúng. Cấu trúc này sau đó có thể có giao diện công khai của riêng nó và được kiểm tra đơn vị. Hãy nhớ rằng, thông thường, hành vi phức tạp trong các phương thức private có thể là dấu hiệu của một lớp có nhiều trách nhiệm hơn. Vì vậy, xin vui lòng, suy nghĩ lại thiết kế của bạn trước.
Didier A.

Vâng, nhưng "mã làm việc" là gì? Kiểm tra một phương pháp riêng tư không nói gì về việc đối tượng của bạn có hành vi phù hợp hay không. Đó là điểm chính tại sao chúng tôi chỉ thử nghiệm các phương pháp công khai. Chỉ các phương thức công khai mới thể hiện hành vi mà người dùng đoạn mã quan tâm.
Sammi

1
"Mã làm việc" là mã hoạt động. Nếu có lỗi trong phương thức riêng tư (hoặc gần như riêng tư) của bạn mà các bài kiểm tra không bắt được (các) phương thức công khai của bạn, thì đã xảy ra lỗi. Có thể thiết kế của bạn là sai, đủ công bằng: Tôi đồng ý rằng giải pháp tốt nhất là các thử nghiệm gọi các phương pháp công khai. Nhưng điều đó không phải lúc nào cũng khả thi, đặc biệt nếu bạn đang thêm hoặc sửa mã cũ. (Tôi nói từ kinh nghiệm, trong một dự án với 1 triệu dòng mã.) Mã đã kiểm tra luôn tốt hơn mã chưa được kiểm tra, thời gian. Ngay cả khi chúng tôi đã phá vỡ các quy tắc tốt đẹp về việc chỉ thử nghiệm các phương pháp công khai!
Charles Roth

Bit (ở trên cùng) về "các bài kiểm tra đang ghép mã ... ngăn việc tái cấu trúc" là sai 100%. Trong phép ẩn dụ kiến ​​trúc, các bài kiểm tra là giàn giáo, không phải bê tông. Mọi thứ thay đổi, bài kiểm tra thay đổi, loại bỏ, bài kiểm tra mới được viết. Tôi đồng ý rằng thiết kế tốt giảm thiểu việc viết lại thử nghiệm. Nhưng thay đổi vẫn xảy ra, ngay cả với những thiết kế tốt nhất.
Charles Roth

34

Bạn đã viết:

Trong phát triển TDD, điều đầu tiên bạn thường làm là tạo giao diện và sau đó bắt đầu viết các bài kiểm tra đơn vị của bạn dựa trên giao diện đó. Khi bạn tiến bộ qua quy trình TDD, bạn sẽ kết thúc việc tạo một lớp triển khai giao diện và sau đó tại một thời điểm nào đó, bài kiểm tra đơn vị của bạn sẽ vượt qua.

Vui lòng để tôi diễn đạt lại điều này bằng ngôn ngữ BDD :

Khi mô tả lý do tại sao một lớp có giá trị và cách nó hoạt động, điều đầu tiên bạn thường làm là tạo một ví dụ về cách sử dụng lớp, thường thông qua giao diện của nó *. Khi bạn thêm hành vi mong muốn, bạn sẽ tạo ra một lớp cung cấp giá trị đó và sau đó tại một thời điểm nào đó, ví dụ của bạn sẽ hoạt động.

* Có thể là một InterfaceAPI thực tế hoặc đơn giản là API có thể truy cập của lớp, ví dụ: Ruby không có giao diện.

Đây là lý do tại sao bạn không thử nghiệm các phương thức riêng tư - bởi vì thử nghiệm là một ví dụ về cách sử dụng lớp và bạn thực sự không thể sử dụng chúng. Một cái gì đó bạn có thể làm nếu bạn muốn là ủy quyền các trách nhiệm trong các phương thức riêng tư cho một lớp cộng tác, sau đó giả lập / khai báo trình trợ giúp đó.

Với các phương thức được bảo vệ, bạn đang nói rằng một lớp mở rộng lớp của bạn nên có một số hành vi cụ thể và cung cấp một số giá trị. Sau đó, bạn có thể sử dụng các phần mở rộng của lớp mình để chứng minh hành vi đó. Ví dụ: nếu bạn đang viết một lớp tập hợp có thứ tự, bạn có thể muốn chứng minh rằng hai phần mở rộng có cùng nội dung thể hiện sự bình đẳng.

Hi vọng điêu nay co ich!


1
Bài viết rực rỡ. Làm sáng tỏ rất nhiều.
frostymarvelous

17

Khi bạn đang viết các bài kiểm tra đơn vị cho lớp của mình, bạn không nhất thiết phải quan tâm xem chức năng của lớp có được triển khai trực tiếp trong phương thức trên giao diện công khai hay không hoặc nếu nó được triển khai trong một loạt phương thức riêng tư. Vì vậy, có, bạn nên thử nghiệm các phương pháp riêng tư của mình, nhưng bạn không cần phải gọi chúng trực tiếp từ mã thử nghiệm của mình để làm như vậy (thử nghiệm trực tiếp các phương pháp riêng tư sẽ kết hợp chặt chẽ việc triển khai với các thử nghiệm của bạn và khiến việc cấu trúc lại trở nên khó khăn không cần thiết).

Các phương thức được bảo vệ tạo thành một hợp đồng khác giữa lớp của bạn và các lớp con tương lai của nó, vì vậy bạn thực sự nên thử nghiệm nó ở mức độ tương tự như giao diện công khai của bạn để đảm bảo rằng hợp đồng được xác định và thực thi tốt.


13

Không! Chỉ giao diện thử nghiệm.

Một trong những lợi ích lớn của TDD là đảm bảo rằng giao diện hoạt động bất kể bạn đã chọn triển khai các phương thức riêng tư như thế nào.


11

Hoàn thành những gì những người khác đã nói ở trên, tôi sẽ nói rằng các phương thức được bảo vệ là một phần của một giao diện nào đó: nó chỉ đơn giản là phương thức được tiếp xúc với tính kế thừa thay vì thành phần, đó là điều mà mọi người có xu hướng nghĩ đến khi xem xét các giao diện.

Đánh dấu một phương thức là được bảo vệ thay vì riêng tư có nghĩa là nó được mong đợi được sử dụng bởi mã của bên thứ ba, vì vậy một số loại hợp đồng cần được xác định và kiểm tra, như xảy ra với các giao diện thông thường được xác định bằng các phương thức công khai, mở cho cả kế thừa và cấu thành .


9

Có hai lý do để viết bài kiểm tra:

  1. Khẳng định hành vi mong đợi
  2. Ngăn chặn sự thoái lui của hành vi

Thực hiện (1) Khẳng định hành vi mong đợi:

Khi bạn đang xác nhận hành vi mong đợi, bạn muốn đảm bảo mã hoạt động như bạn nghĩ. Đây thực sự là một cách tự động để thực hiện xác minh thủ công thông thường của bạn mà bất kỳ nhà phát triển nào cũng sẽ thực hiện khi triển khai bất kỳ loại mã nào:

  • Những gì tôi vừa viết có hoạt động không?
  • Vòng lặp này có thực sự kết thúc không?
  • Nó có lặp lại theo thứ tự tôi nghĩ không?
  • Điều này sẽ hoạt động cho một đầu vào rỗng?

Đó là những câu hỏi mà tất cả chúng ta đều trả lời trong đầu và thông thường, chúng ta cũng sẽ cố gắng thực thi mã trong đầu, đảm bảo rằng nó có vẻ hoạt động. Đối với những trường hợp này, việc yêu cầu máy tính trả lời chúng một cách dứt khoát sẽ rất hữu ích. Vì vậy, chúng tôi viết một bài kiểm tra đơn vị để khẳng định rằng nó có. Điều này mang lại cho chúng tôi niềm tin vào mã của mình, giúp chúng tôi tìm ra các khiếm khuyết sớm và thậm chí có thể giúp thực sự triển khai mã.

Bạn nên làm điều này ở bất cứ đâu bạn cảm thấy cần thiết. Bất kỳ mã nào khó hiểu một chút hoặc không tầm thường. Ngay cả những đoạn mã tầm thường cũng có thể được hưởng lợi từ nó. Tất cả là về sự tự tin của chính bạn. Bao lâu để làm điều đó và đi bao xa sẽ phụ thuộc vào sự hài lòng của chính bạn. Dừng lại khi bạn có thể tự tin trả lời Có với: Bạn có chắc điều này hiệu quả không?

Đối với loại thử nghiệm này, bạn không quan tâm đến khả năng hiển thị, giao diện hoặc bất kỳ thứ gì khác, bạn chỉ quan tâm đến việc có mã hoạt động. Vì vậy, có, bạn sẽ thử nghiệm các phương pháp riêng tư và được bảo vệ nếu bạn cảm thấy chúng cần được kiểm tra để bạn trả lời Có cho câu hỏi.

Thực hiện (2) Ngăn chặn sự thoái lui của hành vi:

Khi bạn đã có mã hoạt động, bạn cần phải có một cơ chế để bảo vệ mã này khỏi bị hư hại trong tương lai. Nếu không ai chạm vào nguồn và cấu hình của bạn một lần nữa, bạn sẽ không cần điều này, nhưng trong hầu hết các trường hợp, bạn hoặc những người khác sẽ chạm vào nguồn và cấu hình phần mềm của bạn. Lỗi nội bộ này rất có thể phá vỡ mã làm việc của bạn.

Các cơ chế tồn tại trong hầu hết các ngôn ngữ như một cách để bảo vệ khỏi thiệt hại này. Các tính năng hiển thị là một cơ chế. Một phương pháp riêng tư bị cô lập và ẩn. Đóng gói là một cơ chế khác, nơi bạn chia ngăn mọi thứ để việc thay đổi ngăn khác không ảnh hưởng đến những thứ khác.

Cơ chế chung cho điều này được gọi là: mã hóa đến ranh giới. Bằng cách tạo ranh giới giữa các phần của mã, bạn bảo vệ mọi thứ bên trong một ranh giới khỏi những thứ bên ngoài nó. Các ranh giới trở thành điểm tương tác và hợp đồng mà mọi thứ tương tác với nhau.

Điều này có nghĩa là những thay đổi đối với một ranh giới, bằng cách phá vỡ giao diện của nó hoặc phá vỡ hành vi mong đợi của nó, sẽ làm hỏng và có thể phá vỡ các ranh giới khác dựa vào nó. Đó là lý do tại sao bạn nên có một bài kiểm tra đơn vị, nhắm mục tiêu các ranh giới đó và khẳng định chúng không thay đổi về ngữ nghĩa và hành vi.

Đây là bài kiểm tra đơn vị điển hình của bạn, bài kiểm tra mà hầu hết mọi người đều nói đến khi nhắc đến TDD hoặc BDD. Mục đích là để làm cứng các ranh giới và bảo vệ chúng khỏi sự thay đổi. Bạn không muốn thử nghiệm các phương pháp riêng tư cho việc này, bởi vì phương pháp riêng tư không phải là một ranh giới. Các phương pháp được bảo vệ là một ranh giới hạn chế và tôi sẽ bảo vệ chúng. Chúng không tiếp xúc với thế giới, nhưng vẫn tiếp xúc với các ngăn hoặc "Đơn vị" khác.

Phải làm gì với điều này?

Như chúng ta đã thấy, có một lý do chính đáng để kiểm tra đơn vị các phương pháp công khai và được bảo vệ, vì để khẳng định rằng các giao diện của chúng ta không thay đổi. Và cũng có lý do chính đáng để thử nghiệm các phương pháp riêng tư, để khẳng định rằng việc triển khai của chúng tôi hoạt động hiệu quả. Vì vậy, chúng ta nên đơn vị kiểm tra tất cả chúng?

Có và không.

Đầu tiên : Kiểm tra tất cả các phương pháp mà bạn cảm thấy cần có bằng chứng xác thực rằng nó hoạt động trong hầu hết các trường hợp để có thể tự tin rằng mã của bạn hoạt động, bất kể mức độ hiển thị. Sau đó, vô hiệu hóa các kiểm tra đó. Họ đã hoàn thành công việc ở đó.

Cuối cùng : Viết các bài kiểm tra cho ranh giới của bạn. Có một bài kiểm tra đơn vị cho mỗi điểm sẽ được sử dụng bởi các đơn vị khác trong hệ thống của bạn. Đảm bảo rằng kiểm tra này khẳng định hợp đồng ngữ nghĩa, tên phương thức, số lượng đối số, v.v. Và cũng đảm bảo kiểm tra xác nhận hành vi có sẵn của đơn vị. Bài kiểm tra của bạn phải chứng minh cách sử dụng thiết bị và những gì thiết bị có thể làm. Giữ cho các thử nghiệm này được bật để chúng chạy trên mọi lần đẩy mã.

LƯU Ý: Lý do bạn tắt bộ kiểm tra đầu tiên là để cho phép công việc tái cấu trúc xảy ra. Kiểm tra hoạt động là một khớp nối mã. Nó ngăn chặn việc sửa đổi mã mà nó đang thử nghiệm trong tương lai. Bạn chỉ muốn điều này cho các giao diện và hợp đồng tương tác của mình.


1
Bạn làm cho nó giống như nếu bạn không thử nghiệm các phương pháp riêng tư một cách rõ ràng, chúng không được đề cập trong các thử nghiệm của bạn và bạn không thể tin tưởng chúng hoạt động. Tôi khẳng định điều này chỉ đơn giản là sai. Một phương thức riêng tư (hoặc bất kỳ đường dẫn mã nào trong đó) không thể được kiểm tra thông qua một phương thức công khai là mã chết và cần được loại bỏ. Toàn bộ điểm của TDD là chỉ có thể kiểm tra các phương pháp công khai, bởi vì bạn viết 0 LoC không tồn tại để vượt qua kiểm tra. Việc thử nghiệm một phương pháp private riêng biệt CHỈ phục vụ cho việc tái cấu trúc khó hơn, điều ngược lại với (một trong các) mục tiêu của TDD.
sara

@kai Tôi tuyên bố rõ ràng rằng bạn không nên có các thử nghiệm tự động cho các phương pháp riêng tư, nhưng đôi khi có các thử nghiệm riêng biệt để giúp bạn triển khai cũng có giá trị. Những thử nghiệm đó không nên là một phần của bộ thử nghiệm của bạn, hoặc nên bị vô hiệu hóa vì lý do bạn đã đề cập: tái cấu trúc. Tùy thuộc vào mức độ tin cậy của riêng bạn để quyết định khi nào bạn thích có một thử nghiệm có lập trình để triển khai một phương pháp riêng tư hay không. Có lẽ bạn đã không đọc đến cuối câu trả lời của tôi?
Didier A.

bạn khẳng định rằng "cũng có lý do chính đáng để thử nghiệm các phương pháp riêng tư, để khẳng định rằng việc triển khai của chúng tôi hoạt động". Tôi thấy không có cơ sở cho điều này trong bài đăng. Không có gì một thử nghiệm của một phương pháp riêng tư có thể cho bạn biết về việc triển khai hoạt động mà một thử nghiệm của một phương pháp công khai cũng không thể cho bạn biết. Phương thức private hoặc hoạt động hoặc không. Nếu nó không hoạt động, nó sẽ làm cho việc kiểm tra một hoặc nhiều phương thức công khai không thành công hoặc nó đã chết và / hoặc mã chưa được kiểm tra.
sara

@kai Bạn đề cập: "hoặc mã đã chết và / hoặc chưa được kiểm tra". Mã chưa được kiểm tra là những gì tôi đang nói đến. Một phương thức private có thể ẩn rất nhiều lỗi mà các trường hợp cạnh không được thực thi từ các phương thức public. Hãy tưởng tượng một lỗi xảy ra. Đôi khi, các bất biến của các phương thức công cộng làm cho nó nên trường hợp này sẽ không bao giờ xảy ra. Trong trường hợp như vậy, tôi cho rằng phương thức private vẫn còn nhiều lỗi và triển khai có sai sót, tuy nhiên, việc tích hợp của nó ngăn không cho tìm và bắt lỗi. Trong trường hợp này, bạn có thể muốn một vài thử nghiệm để thử các trường hợp cạnh để bạn có thể chắc chắn rằng phương pháp của mình không có lỗi.
Didier A.

@kai Nhưng, hãy hiểu rằng những thử nghiệm tôi đang nói đến không phải là bộ thử nghiệm của bạn, đây không phải là TDD. Tôi đang nói rằng, một số phương pháp riêng tư được thực hiện dễ dàng hơn nếu bạn có thể nhanh chóng chạy một số thử nghiệm chống lại chúng. Trong các ngôn ngữ có REPL, bạn không cần nhiều như vậy. Và bạn có thể thử xem qua phương pháp trong đầu, nhưng tôi khuyên bạn nên thực hiện các bài kiểm tra do máy tính chạy thay vì chỉ những phương pháp riêng tư khó thực hiện. Tôi khuyên bạn nên xóa các bài kiểm tra sau đó hoặc giữ chúng ở chế độ vô hiệu hóa hoặc ở vị trí đặc biệt của riêng nó không được chạy trong bản dựng CI của bạn.
Didier A.

4

Không, bạn không nên thử nghiệm các phương pháp riêng tư (bạn sẽ làm thế nào nếu không sử dụng thứ gì đó khủng khiếp như phản chiếu). Với các phương thức được bảo vệ, hơi ít rõ ràng hơn trong C #, bạn có thể đặt mọi thứ được bảo vệ bên trong và tôi nghĩ rằng bạn có thể làm điều đó để kiểm tra các lớp dẫn xuất triển khai tất cả chức năng của chúng thông qua các phương thức mẫu mẫu.

Tuy nhiên, nói chung, nếu bạn nghĩ rằng các phương thức public của bạn đang hoạt động quá nhiều thì đã đến lúc cấu trúc lại các lớp của bạn thành các lớp nguyên tử hơn và sau đó kiểm tra các clases đó.


2

Tôi cũng đồng ý với câu trả lời của @ kwbeam về việc không thử nghiệm các phương pháp riêng tư. Tuy nhiên, một điểm quan trọng mà tôi muốn nhấn mạnh - các phương thức được bảo vệ LÀ một phần của API xuất của một lớp và do đó PHẢI được kiểm tra.

Các phương thức được bảo vệ có thể không được truy cập công khai nhưng bạn chắc chắn đang cung cấp một cách để các lớp con sử dụng / ghi đè chúng. Một cái gì đó bên ngoài lớp có thể truy cập chúng và do đó bạn cần đảm bảo rằng những thành viên được bảo vệ đó hoạt động theo cách mong đợi. Vì vậy, đừng thử nghiệm các phương pháp riêng tư mà hãy thử nghiệm các phương pháp công khai và được bảo vệ.

Nếu bạn tin rằng bạn có một phương thức riêng chứa logic quan trọng, tôi sẽ cố gắng giải nén nó thành một đối tượng riêng biệt, cô lập nó và cung cấp một cách để kiểm tra hành vi của nó.

Hy vọng nó giúp!


2

Nếu bạn đang nhắm đến độ phủ mã cao (tôi khuyên bạn nên làm như vậy), bạn nên thử nghiệm tất cả các phương pháp của mình bất kể chúng là riêng tư hay được bảo vệ.

Được bảo vệ là một loại điểm thảo luận khác nhau, nhưng tóm lại, nó hoàn toàn không nên ở đó. Hoặc nó phá vỡ tính đóng gói trên mã đã triển khai hoặc nó buộc bạn phải kế thừa từ lớp đó, chỉ để đơn vị kiểm tra nó, thậm chí đôi khi bạn không cần kế thừa.

Chỉ ẩn một phương thức cho khách hàng (đặt ở chế độ riêng tư) không cho phép nó có đặc quyền không bị kiểm toán. Do đó, chúng có thể được kiểm tra bằng các phương pháp công khai như đã đề cập trước đây.


1

Tôi đồng ý với mọi người: Câu trả lời cho câu hỏi của bạn là 'không'.

Thật vậy, bạn hoàn toàn chính xác với cách tiếp cận và suy nghĩ của mình, đặc biệt là về độ bao phủ của mã.

Tôi cũng muốn nói thêm rằng câu hỏi (và câu trả lời 'không') cũng áp dụng cho các phương thức công khai mà bạn có thể giới thiệu cho các lớp.

  • Nếu bạn thêm các phương thức (công khai / được bảo vệ hoặc riêng tư) vì chúng khiến bài kiểm tra không đạt, thì ít nhiều bạn đã đạt được mục tiêu của TDD.
  • Nếu bạn thêm các phương thức (công khai / được bảo vệ hoặc riêng tư) vì bạn vừa quyết định vi phạm TDD, thì phạm vi mã của bạn sẽ nắm bắt được những điều này và bạn sẽ có thể cải thiện quy trình của mình.

Ngoài ra, đối với C ++ (và tôi chỉ nên nghĩ cho C ++), tôi triển khai các giao diện chỉ sử dụng các phương thức riêng tư, để chỉ ra rằng lớp chỉ nên được sử dụng thông qua giao diện mà nó thực hiện. Nó ngăn tôi gọi nhầm các phương pháp mới được thêm vào quá trình triển khai từ các thử nghiệm của tôi


0

Một thiết kế tốt có nghĩa là chia ứng dụng thành nhiều đơn vị có thể kiểm tra được. Sau khi thực hiện việc này, một số đơn vị được tiếp xúc với API công khai, nhưng một số đơn vị khác có thể không. Ngoài ra, các điểm tương tác giữa các đơn vị được tiếp xúc và các đơn vị "nội bộ" này cũng không phải là một phần của API công khai.

Tôi nghĩ rằng một khi chúng tôi có đơn vị có thể nhận dạng, sẽ được hưởng lợi từ các bài kiểm tra đơn vị, bất kể có được hiển thị thông qua API công khai hay không.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.