Nếu bạn có nghĩa là riêng tư theo cách tôi nghĩ bạn có nghĩa là nó, thì không - bạn không nên đơn vị kiểm tra nó. Bạn chỉ nên là đơn vị kiểm tra hành vi / trạng thái quan sát được. Bạn có thể đang thiếu điểm đằng sau chu trình "đỏ-xanh-tái cấu trúc" của TDD (và nếu bạn không thực hiện kiểm tra trước thì áp dụng nguyên tắc tương tự). Khi các bài kiểm tra được viết và vượt qua, bạn không muốn chúng thay đổi trong khi thực hiện tái cấu trúc. Nếu bạn buộc phải kiểm tra đơn vị chức năng riêng tư thì có lẽ điều đó có nghĩa là đơn vị kiểm tra xung quanh chức năng công cộng bị thiếu sót. Nếu việc viết các bài kiểm tra xung quanh mã công khai là khó khăn và phức tạp thì có thể lớp của bạn đang làm quá nhiều hoặc vấn đề của bạn không được xác định rõ ràng.
Tồi tệ hơn, theo thời gian các bài kiểm tra đơn vị của bạn sẽ trở thành một quả bóng và chuỗi làm bạn chậm lại mà không thêm bất kỳ giá trị nào (thay đổi thực hiện, ví dụ như tối ưu hóa hoặc loại bỏ trùng lặp, sẽ không ảnh hưởng đến các bài kiểm tra đơn vị). Tuy nhiên, mã nội bộ phải được kiểm tra đơn vị vì hành vi / trạng thái có thể quan sát được (chỉ trong một cách hạn chế).
Khi tôi lần đầu tiên thực hiện kiểm tra đơn vị, tôi đã rút ra tất cả các loại thủ thuật để kiểm tra đơn vị riêng tư nhưng bây giờ, với một vài năm trong vành đai của tôi, tôi thấy nó còn tệ hơn cả lãng phí thời gian.
Đây là một ví dụ ngớ ngẩn, tất nhiên trong cuộc sống thực, bạn sẽ có nhiều bài kiểm tra hơn:
Giả sử bạn có một lớp trả về một danh sách các chuỗi được sắp xếp - bạn nên kiểm tra xem kết quả đã được sắp xếp chưa, chứ không phải cách nó thực sự sắp xếp danh sách đó. Bạn có thể bắt đầu thực hiện với một thuật toán duy nhất sắp xếp danh sách. Khi đã xong, bài kiểm tra của bạn không cần thay đổi nếu bạn thay đổi thuật toán sắp xếp của mình. Tại thời điểm này, bạn có một bài kiểm tra duy nhất (giả sử rằng việc sắp xếp được nhúng trong lớp của bạn):
- Là kết quả của tôi được sắp xếp?
Bây giờ hãy nói rằng bạn muốn có hai thuật toán (có thể một thuật toán hiệu quả hơn trong một số trường hợp nhưng không phải là thuật toán khác), thì mỗi thuật toán có thể (và nói chung, nên) được cung cấp bởi một lớp khác và lớp của bạn chọn từ chúng - bạn có thể kiểm tra điều này đang xảy ra kịch bản đã chọn của bạn bằng cách sử dụng giả, nhưng thử nghiệm ban đầu của bạn vẫn hợp lệ và vì chúng tôi chỉ xác minh hành vi / trạng thái có thể quan sát được nên không cần thay đổi. Bạn kết thúc với 3 bài kiểm tra:
- Là kết quả của tôi được sắp xếp?
- Đưa ra một kịch bản (giả sử danh sách ban đầu gần như được sắp xếp để bắt đầu) là một cuộc gọi được thực hiện cho lớp sắp xếp các chuỗi bằng thuật toán X?
- Đưa ra một kịch bản (danh sách ban đầu theo thứ tự ngẫu nhiên) là một cuộc gọi được thực hiện cho lớp sắp xếp các chuỗi bằng thuật toán Y?
Giải pháp thay thế sẽ là bắt đầu kiểm tra mã riêng trong lớp của bạn - bạn không thu được gì từ điều này - các thử nghiệm trên cho tôi biết mọi thứ mà tôi cần biết khi có liên quan đến kiểm thử đơn vị. Bằng cách thêm các bài kiểm tra riêng tư, bạn sẽ tự tạo cho mình một chiếc áo khoác thẳng, sẽ còn bao nhiêu công việc nữa nếu bạn không chỉ kiểm tra xem kết quả đã được sắp xếp mà còn cả cách sắp xếp?
Các thử nghiệm (thuộc loại này) chỉ nên thay đổi khi hành vi thay đổi, bắt đầu viết thử nghiệm đối với mã riêng và điều đó xuất hiện ngoài cửa sổ.