A good unit test should be:
Idempotent: It’s every engineer favorite word :) Meaning it can be run over and over and is always green.
Independent/Atomic: Meaning it does not dependent on any other tests to run before and can be run at any order or randomly within a test suite
If we are not able to achieve the above, then our unit test will become flaky and a bad (very bad) unit test. It will be flagged with an ignore tag or worst either commented out or deleted all together.
In addition, our unit test should be fast: It should run quickly so it does not delay the development process. This means that all the unit test dependencies should be mocked.
Side note - the only place where not mocking might be okay (and it is debatable) is for an orm heavy app where we can launch a database in memory. I still think it should be mocked but there is a counter argument to be said that not mocking might lead to a more accurate test through relying on actual db data and operations rather than orm mocks.
The unit test title should explain what it does. I recommend testWhenShould pattern in the title but other patterns are okay too. I also recommend having three sections: setup, execute and validate.
In the end, your test should be similar to this:
test*When*Should* {
//setup
.
dependencyOne = mockDependencyOne.return({…});
dependencyTwo = mockDependencyTwo.return({…});
objectToBeTested = new ObjectToBeTested(dependencyOne, dependencyTwo);
//execute
result = objectToBeTested.someFunc();
//validate
assertEquals(result, expectedResult)
}
Unit test code is no less important than product code and should follow the guidelines of elegant code too.
Finally, one last tip I posted about before. When you fix a bug, check why the previous unit tests did not uncover it and update them accordingly.
Software Engineering from the Frontlines Course on Maven
If you liked this article, I will be teaching a “Software Engineering from the Frontlines” course on Maven where I will teach hard-learned lessons I acquired developing large-scale products at companies such as Uber, Airbnb, and Microsoft.
It is always better to follow such rules:
- use real code for system's under test dependencies
- if not possible, replace it with test double (like in-memory database)
- if not possible, replace it with mock object
- never test behaviour (method X was invoked), test state or returned result
What are some example unit test names? I am not clearly understanding the name format but examples would definitely help