DEV Community

Discussion on: My personal take on TDD

Collapse
 
grahamcox82 profile image
Graham Cox

This idea works really well when the units being tested are self contained. It falls apart when the units being tested are part of a bigger whole.

As an example here. Say I'm writing a user management system. Part of this entails the ability to load users from the database. As such, I've got:

  • User DAO
  • User Retriever ** Implementation of this that works directly in terms of the DAO ** Implementation of this that does caching
  • User Controller

Each of these should be tested to ensure that they work. But the implementation of the User DAO will directly affect the implementation of the Dao User Retriever.

An Integration test of this as a whole - from the controller to the database - makes a lot of sense to do ahead of times. You know what your API inputs and outputs are going to be, because they are part of your design. You know that when you call "GET /users/unknown" then you expect an HTTP 404, and when you call "GET /users/graham" then you expect an HTTP 200, and a JSON document in a specific format. You can write all of these first.

Unit Tests for the individual classes can be written ahead of time, but in my experience I've always ended up changing them as I write the code because of refectorings and tidying up and things like this. Little details like how the DaoUserRetriever works might change how the UserDao itself needs to work, which will change the unit tests for the UserDao.

And regarding the comment about mocks - if you don't use mocks then either you are writing everything as pure functions, or else you aren't doing Unit Testing. When testing that the DaoUserRetriever works correctly, you have to provide some implementation of the UserDao. Either the real one - which means instantly it's not a Unit Test - or else a Mock one.