While practicing TDD, I came across this specification:

A user should be created with its password hashed, be persisted and an activation token should be returned.

Should my first unit test, (aiming to begin to test this scenario) should encompass the whole needs? :


Or rather, splitting its main parts into several smaller tests, and testing incrementally:


To put in a nutshell, should I rework the same test until a whole scenario passes? Or should I proceed incrementally by specifying additional features in other small tests.

IMHO, the benefit of the first solution is that the spec is defining in one place, no need to gather some chuncks of features to figure out the whole. On the other hand, the number of assertions and expectations might be huge, therefore the test code would be less readable.


1 Answer 1


tl;dr: Second option. You should split into several smaller tests, as that is what you're supposed to do with TDD (Red-Green-Refactor).

You start writing the simplest tests first to start out with the simplest implementation and build your way up towards a full scenario. The semantics with unit tests is totally different with scenario/functional/acceptance testing. Developers tend to confuse them all as the same but they're semantically different and fill different purposes.

TDD is built on the concept where a test has the granularity of a unit. Usually this unit is down to a method in a class. The whole point with TDD is to design code to be testable. If you start with a whole scenario as a unit and not the actual methods themselves you'll end up with code that may be doing too much.

There are different ways to go about with your scenario. I would roughly start by trying the following:

  1. First write a UserService that can create a new user with a single test createUserShouldReturnUser.
  2. Then write a IActivationTokenFactory interface that creates activation tokens. On UserService I'd continue with a test that uses the token factory as a mock object. The test is createUserShouldRequestActivationToken that requests any activation token from the mock object and puts it on the user object that is returned.
  3. I proceed to write a concrete ActivationTokenFactory that implements IActivationTokenFactory. The test is to make sure it produces "legit" tokens.
  4. and so on... I can imagine some kind of HashFactory object and some kind of persistance layer would be created as well.

Rinse, repeat until I have a full scenario and refactor along the way. I'd write the scenario test by now that exercises all the code, and make sure I have some unhappy paths to test as well (with failed persistance exceptions and whatnot).

It's easier to implement something if you divide and conquer... which is what you're supposed to do with TDD. Once you hit a snag, it's good to have these tiny unit tests for regressions if you decide to refactor something.

  • Thus the second suggestion (with several small and cohesive tests) would better fit to TDD, wouldn't it?
    – Mik378
    Jul 23, 2013 at 12:47
  • Awesome answer :) So, your last (and full scenario) would look like: shouldPersistTheNewlyCreatedUserWithAHasedPasswordAndReturnACorrespondingActivationToken with all mocks expectations (gathering the ones from the previous cohesive tests)? The difference being that I ended up with a code designed by my first cohesive tests :) Thanks a lot!
    – Mik378
    Jul 23, 2013 at 12:56

Not the answer you're looking for? Browse other questions tagged or ask your own question.