Do unit tests sometimes break encapsulation? [duplicate]

I very often hear the following: “If you want to test private methods, you’d better put that in another class and expose it.”

While sometimes that’s the case and we have a hiding concept inside our class, other times you end up with classes that have the same attributes (or, worst, every attribute of one class become a argument on a method in the other class) and exposes functionality that is, in fact, implementation detail.

Specially on TDD, when you refactor a class with public methods out of a previous tested class, that class is now part of your interface, but has no tests to it (since you refactored it, and is a implementation detail).

Now, I may be not finding an obvious better answer, but if my answer is the “correct”, that means that sometimes writting unit tests can break encapsulation, and divide the same responsibility into different classes.

A simple example would be testing a setter method when a getter is not actually needed for anything in the real code.

Please when aswering don’t provide simple answers to specific cases I may have written. Rather, try to explain more of the generic case and theoretical approach. And this is neither language specific.

Thanks in advance.

EDIT: The answer given by Matthew Flynn was really insightful, but didn’t quite answer the question. Although he made the fair point that you either don’t test private methods or extract them because they really are other concern and responsibility (or at least that was what I could understand from his answer), I think there are situations where unit testing private methods is useful. My primary example is when you have a class that has one responsibility but the output (or input) that it gives (takes) is just too complex. For example, a hashing function. There’s no good way to break a hashing function apart and maintain cohesion and encapsulation. However, testing a hashing function can be really tough, since you would need to calculate by hand (you can’t use code calculation to test code calculation!) the hashing, and test multiple cases where the hash changes. In that way (and this may be a question worth of its own topic) I think private method testing is the best way to handle it. Now, I’m not sure if I should ask another question, or ask it here, but are there any better way to test such complex output (input)?

OBS: Please, if you think I should ask another question on that topic, leave a comment. 🙂

EDIT2: I accepted an answer as my correct because it made me think and decide my course of action, although it didn’t answered my question completely. But for those who face the same problem as I do (one cohesive class that will change together, but is still too hard to test by itself), I’ll tell what I did and why. I decided that the output of that class is simply too hard to a computer to test correctly, so I didn’t test it. I could have used a framework to test it’s private methods (which would be the best idea, I think), but I didn’t want to get to that point. If you are wondering what it is that is cohesive and respects SRP, and still is too hard to a computer to test, I’ll give some examples: heightmap generation, hashing functions, procedural music generation (you can test some units, but the highest level unit is simply too subjective).

2

When I was younger and raised this question, I was told that I really don’t need to write unit tests for private methods. Surprisingly, this turned out to be true.

If you take a behavioral driven approach to unit tests, this makes perfect sense–your public methods are what are being asked to do stuff. The fact that they call internal private methods is orthogonal to their outward behavior. Because the other method is private/encapsulated, it really is part of the unit being tested.

You may ask that if multiple methods in your class all call a single private method, so shouldn’t you be testing that that one method works? The answer here is yes, but it is not made evident by a unit test of the private method, but rather the unit tests of the public methods calling it. If the public methods work, and they call a private method, then the private method must also work.

11

When you feel the urge to test private methods, you’re simply doing it wrong. It might be okay to factor out a complicated algorithm of a private method to a separate, “more public” class, and use this class in the original private method. But the point is this still doesn’t break encapsulation.

If you make something private, it is not part of the API of the class, it just doesn’t exist for the outside world. If something happens there which is really important, and should be tested in your opinion, but can’t be properly detected through the API, then something in your API design is broken. You have to decide if something matters, or if it is an implementation detail. It can’t be both.

3

Whilst I don’t disagree with the answers that say “Private is Private” and in most cases this is true, it isn’t always.

If your code product is part of a certificated safety-critical product (eg aerospace, medical, automotive) then you will come across test coverage requirements, and such delights as Modified Condition/Decision Coverage

Saying to the Certification Body that you haven’t tested the internals of your class, because private is private will not get you a tick in the box.

Only testing the public interface of a class is Black Box testing… and as long as the results are OK, then (in most cases) that is enough. But sometimes, you need to do White Box testing, and validate the nuts and bolts inside.

I emphasise the sometimes but (as with most “rules”) never say “never test the private”.

1

First of all, not code, but class behavior is what is tested. Code is just a way to make the class work as expected, but code isn’t required at all 🙂 It would be actually better to make your class work without writing code (OFF TOPIC).

Public methods call private methods, so testing public methods should always be enough. When using TDD, you should write tests before the implementation, so it’s impossible to test private methods.

As for health-critical software and stuff like that, hitting 100% path coverage by testing private methods will not ensure that tested software works correctly in 100% of cases. You can be sure only after testing all possible input data on all possible object states. Doing this for only public methods should cover all paths in private methods.

There is sometimes value in testing having access to protected/private members.

Suppose you have an initialisation function – you want to test that certain internal variables have been set. The easiest way to do this is for your testing framework to have access to those variables, generally either the testclass derives from the class or there is some trick to convert protected->public during test.

You could add public() functions to return the value of all the protected variables – but that would break encapsulation rather more.

2

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa
Thiết kế website Thiết kế website Thiết kế website Cách kháng tài khoản quảng cáo Mua bán Fanpage Facebook Dịch vụ SEO Tổ chức sinh nhật