Write Unit Tests Against the Interface, Not Implementation

preview_player
Показать описание
Unit testing is considered by many as a critical aspect of software development, ensuring that your application behaves as expected. But how often does it happen to your unit tests to break due to unrelated changes in your implementation? If you feel your unit tests are brittle, you're not alone!
In this video, we are shedding light on the problem of fragility in unit tests. We are dissecting the common pitfall of constructing unit tests that are overly reliant on specific implementation details, resulting in brittle tests.
The video uses a real-world scenario from a monetary application to showcase how a test can fail with the slightest shift in implementation. Most notably: a change that is not related to the feature covered by the test!
But we don't stop at just highlighting the problem; this video offers a solution. The tutorial provides an effective strategy for designing resilient tests, which are less likely to fail when the implementation changes. Watch this video and gain deep insights into constructing unit tests that stand the test of time, to a great measure regardless of how your implementation evolves.

Thank you so much for watching! Please like, comment & share this video as it helps me a ton!! Don't forget to subscribe to my channel for more amazing videos and make sure to hit the bell icon to never miss any updates.🔥❤️

⭐ Learn more from video courses:

▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬
⭐ CONNECT WITH ME 📱👨

▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬
👨 About Me 👨
Hi, I’m Zoran, I have more than 20 years of experience as a software developer, architect, team lead, and more. I have been programming in C# since its inception in the early 2000s. Since 2017 I have started publishing professional video courses at Pluralsight and Udemy and by this point, there are over 100 hours of the highest-quality videos you can watch on those platforms. On my YouTube channel, you can find shorter video forms focused on clarifying practical issues in coding, design, and architecture of .NET applications.❤️
▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬
⚡️RIGHT NOTICE:
The Copyright Laws of the United States recognize a “fair use” of copyrighted content. Section 107 of the U.S. Copyright Act states: “Notwithstanding the provisions of sections 106 and 106A, the fair use of a copyrighted work, including such use by reproduction in copies or phono records or by any other means specified by that section, for purposes such as criticism, comment, news reporting, teaching (including multiple copies for classroom use), scholarship, or research, is not an infringement of copyright." This video and our youtube channel, in general, may contain certain copyrighted works that were not specifically authorized to be used by the copyright holder(s), but which we believe in good faith are protected by federal law and the Fair use doctrine for one or more of the reasons noted above.

#csharp #dotnet #vscode
Рекомендации по теме
Комментарии
Автор

Always happy to see a video about unit testing!

malzsmith
Автор

Probably from years of my experience in deploying and servicing accounting, erp and general business application this fact of clearing curency at 0 bothered me in other video too, i thought of other reasons at first but still bothered me.

AK-vxdy
Автор

Another cracking video well done!!. Love to see your view on unit testing services that use Entity Framework. So much confusion in this area as to best approach. I'm using interfaces and mocking it but it does feel quite fragile, however it is very fast and each test is well isolated from the others.

codingbloke
Автор

Outside of this very specific example, I will admit that I struggle to see how this could be applied in a more general sense. This also seems like it's not always that appropriate? Wouldn't there be occasions where I want to be sure that the algorithm implementation is working in a manner that I expect it to?

You could also argue that in this example, the issue is partially due to using the implementation to guide the unit tests, but it's also strongly to do with the test looking at a lot of information that isn't relevant to what the test is actually intending to look at. i.e. Assert.Equal(0, diff.Amount) is perfectly valid (we're checking that the amount should in fact be zero). The stated intent of the test is to confirm that fact, not to check whether the currency type has changed or not.

metallixbrother
Автор

Great advice Zoran! How do you handle testing of void methods though? Since they usually modify internal state or notify someone else, there's little choice but to inject mocks or check an objects state, but this often requires much more knowledge about internals than I want to have.

allinvanguard
Автор

Can the currency type of the money really be considered an implementation detail? From a code perspective, any public method or value is part of the interface, so the fact that currency can be accessed by our "brittle" test at all means that this test seems to be testing the interface of Money. if currency type were a private variable, then i'd agree with you that we shouldn't test for it directly. But then we wouldn't be able to test against it at all because we have no way of accessing it from a test.

Secondly, if your business logic fundemantally changes (IE: the types of currencies that can be added and subtracted changes), then why wouldn't you want a unit test to fail? If I fundamentally changed business logic and didn't see a test fail, that would be a red flag for me because it means that the old business logic didn't have any automated tests that were reinforcing behavior. I could understand if by "implementation detail" you meant wheter we persist to a sql database vs a nosql database, but currency type is a fundamential part of the domain, and busienss users expect this to have a specific behavior regardless of the underlying implementation.

cyropox
Автор

Let's go extreme OO, make every currency subclass of Money 😉

AK-vxdy
Автор

Brittle tests are written after the fact, write them before the implementation.
Legacy code is a challenge to test, often there's nobody around who can tell you what it should be doing.

nickbarton
Автор

if your test isn't testing an implementation what is it testing? The "unrelated" test failed because it tested an implementation and failed because the implementation was no longer valid. So good test

auronedgevicks
Автор

I agree with the fundamental thesis of the video, but the example is not well chosen. It is actually very inappropriate to make the different currency zeroes equal. Comparing different currencies should always throw an exception, it should be forbidden just like doing arithmetic on them, zero or not.

piotrkozbial
Автор

Currency.Empty for 0 Money... fucking genious! 😲

anarhistul
Автор

I think there is another issue with this example. What if there was other code that relies on the currency property to become empty just like the brittle test did. How do we account for that? Wouldn't a brittle test at least give us a hint that there might be a problem we need to address? What do you think?

stefan.wodzicki