Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unit testing method that uses already tested method

Tags:

unit-testing

Assume we have class Handler and class Validator. The Handler uses Validator to validate incoming requests.

The Validator class is unit tested, whether returns appropriate error etc.

Later, we want to create unit tests for Handler. The Validator has already unit tests, so how would the test for Handler look?

Will we write the same tests as for Validator whether Handler returns the appropriate error (retrieved from Validator class)? It doesn't make sense to me.

So how would the unit test for Handler class look in this case?

like image 873
Szyszka947 Avatar asked Aug 25 '26 14:08

Szyszka947


1 Answers

The mocking solution that Mureinik presented in his answer is indeed the textbook solution. It is what most people on the planet do, and what most people consider normal. In my opinion, it is also deeply misguided, and I am not the only one who thinks this way:

  • In the video Thoughtworks - TW Hangouts: Is TDD dead? (youtube) at 21':10'' Kent Beck (Wikipedia) says "My personal practice is I mock almost nothing."
  • In the same video, at 23':56'' Martin Fowler (Wikipedia) adds "I'm with Kent, I hardly ever use mocks."
  • In the Fragile Test section of his book xUnit Test Patterns: Refactoring Test Code (xunitpatterns.com) author Gerard Meszaros states "extensive use of Mock Objects causes overcoupled tests."
  • In his presentation TDD, where did it all go wrong? (InfoQ, YouTube) at 49':32'' Ian Cooper says "I argue quite heavily against mocks because they are overspecified."

If you would like to read more about why mocks are a bad idea, see my blog post: michael.gr - On Mock Objects and Mocking

A better way to handle this is a method that I call Incremental Integration Testing. This means never mock anything, always integrate the actual dependencies in your tests, (or fakes thereof, but never mocks,) and simply arrange the order in which your tests are executed so that the most dependent-upon classes are tested first, and classes that depend on them are tested afterwards. This way, the test for the Handler can make use of the Validator and take it for granted that it works, because the test for the Validator has already run, and it has passed.

Unfortunately, testing frameworks offer very little, if any, support for executing tests in a particular order. I have written a tool that will take care of this for maven-based java projects, but you might not be using java, or maven, or you might not be willing to use some weird tool that some guy built. Luckily, there is a manual workaround: Testing frameworks tend to execute tests in alphabetic order, so you can still enforce the order of execution of your tests by naming them in such a way that their alphabetic order coincides with the order in which they should be executed. For example, you can name your tests T01_ValidatorTest, T02_HandlerTest, etc. so that the test for Validator always runs before the test for Handler. You might also have to similarly name your packages and/or namespaces.

For more information about Incremental Integration Testing see my blog: michael.gr - Incremental Integration Testing

like image 70
Mike Nakis Avatar answered Aug 30 '26 10:08

Mike Nakis



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!