5 things that make your unit testing painful

Paweł Sadowski
4 min readMay 5, 2021
Photo by Arnold Francisca on Unsplash

1. Testing implementation details

Have you ever made some method in class public just to write a test for it? Did you use some complier magic to make internal members visible to your test project? If any of this sound familiar, then you probably focus your tests too much on implementation details.

In my opinion it’s by far most common problem among developers. All tutorials on unit testing for beginners show some class with public method looking something like this AddTwoNumbers(int a, int b) Then they teach how to check if this method works correctly. This leads to false impression that unit test should always cover something as small as one method with two lines of code.

When I started my way with unit testing, I was refactoring my code until it was split in number of tiny methods and then I was writing tests for each one separately. What is the effect? You have tens of tests that need to be updated after every smallest refactoring. Nobody else can wrap their head around what you are testing there and how this should really work.

What you should do instead?

Test behaviour of the code. Test your public API. When you work on adding item to cart in ecommerce, write test that as an input provides ProductId and asserts that when you call GetMyCartItems the code will return added product. Don’t test all the smallest steps that are done on the way. If you write a method that is supposed to break enigma code just write tests that puts some encrypted text in check if it was correctly decrypted.

There is one exception. If you like writing tests for internal parts of your code because it helps you understand the problem and brings you closer to solution, then why not. But after you get to solution and you have working code, then delete all this tests. Make your internals private again and focus on public API.

2. Too extensive mocking

This goes hand in hand with previous topic. You usually split your implementation in many separate classes and then you start mocking everyone of them. In the end you waste so much time setting up fake values on them. Before mocking think if the component you try to replace is really external dependency or is it part of implementation that was just moved to separate class for more readability. Mocking should save you time not make your life more difficult.

3. Trying to mock DB at all cost.

When you are working on some CRUD or legacy system where the database is heart of the app don’t try to mock it. If your business logic is separated from persistence layer then that’s great and you don’t need to mock anything. But if you are in this unfortunate situation where you call some ORM directly in request handler then don’t rush straight into mocking. Try writing tests that utilize DB. If you are happy with performance, then leave it as it is. If not there is still many things you can do. Before going for mocking db try optimizing db deployment or use in memory database.

4. Leaving test for the end

Implementing tests after you finish feature has negative impact on two levels. First of all you’re already happy that you finished your task. You did all the work, tested code manually, your brain trigger dopamine release to gratify you for your effort. Now writing test will look for you like a punishment. You don’t really see point anymore and you would rather take a new assignment. On top that you see that code you’ve written is not that easy to test because you didn’t take it into consideration in the design phase. That’s why its way better to start your development with writing test and then working toward making it green.

5. To complex tests

This happens when you try to test to much things at once. You get huge test methods that are hard to maintain. Because you’ve put so many asserts there when the test fails you don’t really know why without debugging. It’s far better to have 5 smaller tests covering separate requirements then you huge trying to cover all of them.

Summary

Unit tests are great thing and should make your life easier. If you constantly struggle and hate writing them that means you do something wrong along the way. I hope that this article will help you identify some pain points that you may find in your code. Please let me know about other things you’ve found helpful when writing test or if you have different view on things I’ve presented in this article.

Thanks for reading!

--

--