Testing Rule of Thumb: if it looks too much like the real implementation, doubt it

| 2 min read

This can mean a variety of things.

If you have logic in tests or are doing some calculations be suspicious, especially if this is for the expected value of the assertion. Prefer literal values or variables without any manipulation there.

Another good example is complex mock setup. If you are writing a complex matcher that is a mirror of what you need to write in the implementation you are not testing anything, you are painting by number, but you are the one making the template. Don’t be surprised if the implementation doesn’t do what you expect it to. The only solution here is to introduce some tests that really exercise the thing you mock, following the Don’t mock what you don’t own advice. The classical example of this is people mocking ORMs and writing their queries in the tests and in the implementation. The double the work but still no guarantee that your DB will actually do what you want it to do.

One final example is validating an external message using its internal representation. Here think about APIs schema. You shouldn’t use your API response DTO to construct the expected API response. The test is supposed to validate a contract. If that contract moves when you are modifying the code it isn’t of any help. Imagine that you rename a field in your DTO using an automated refactoring tool. Shouldn’t your test fail and tells you that you are breaking the contract established with your API clients? If you use the same DTO the test will continue passing as both the implementation and the test will be modified. If you don’t preserve the behavior, this is not refactoring. Write your tests in a way that they tell you if are changing behavior: do not build your expectation the same way you are building the actual value.

As you see, if your test looks too much like the implementation, there is possibly something shady.

Whenever you're ready, here is how I can help you: