Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Classes that make it difficult to mock their dependencies usually need to be refactored to follow the Dependency Inversion Principle and use dependency injection. For cases where the class to be mocked is instantiated inside the class multiple times, consider creating and injecting a factory class or a Supplier, or use the Factory Method design pattern.

Tests Need to be Run in a Specific Order

This usually indicates that some tests are not properly cleaning up after themselves or are not properly setting up their test prerequisites.

A Lot of Repeated Test Code

Creating Mocks Manually

Anti-Patterns

Sleeps

Brendan Hofmann I could see an argument that everything in this category should be in component tests instead of unit tests.

Test Multiple Behaviors in a Single Test

A test should test one and only one behavior. Having assertions and/or verifications that validate different behaviors makes it difficult to know why a test has failed and doesn't provide a good insight into what is being tested.

Repeated Given, When or Then sections in a BDD test, or difficult to name tests are usually two good indicators that a test is doing too much.

Comment:

  • How do you write tests that build on top of each other?
  • Brendan Hofmann What is the right way to unit test sequential behaviors then? We should provide positive guidance to follow instead.

Anti-Patterns

Sleeps

Sleeps in tests should be avoided as they open the door to timing issues and race conditions, slow tests down and are a major cause of test flakiness.

...

  • Replaced the sleep with an active wait loop (a.k.a., polling), i.e., wait until a condition has been met before moving on
  • Use external synchronization, i.e., use existing class notification mechanism to know it has reached a certain state before continuing
  • Refactor the code under test to eliminate concurrency
  • Use external dependency calls or side-effects as synchronization points in the tests
  • For unit or component tests, replace (using dependency injection) Executor objects with MoreExecutors.directExecutor() and ExecutorService objects with MoreExecutors.newDirectExecutorService() to make the code and test single-threaded

Test Multiple Behaviors in a Single Test

A test should test one and only one behavior. Having assertions and/or verifications that validate different behaviors makes it difficult to know why a test has failed and doesn't provide a good insight into what is being tested.

Repeated Given, When or Then sections in a BDD test, or difficult to name tests are usually two good indicators that a test is doing too much.

...

Undoing Setups in Specific Tests

Tests Need to be Run in a Specific Order

This usually indicates that some tests are not properly cleaning up after themselves or are not properly setting up their test prerequisites.