๐๐จ๐๐ ๐ฌ๐ฆ๐๐ฅ๐ฅ ๐๐๐ญ๐๐๐ญ๐ข๐จ๐ง ๐ฏ๐ข๐ ๐ฎ๐ง๐ข๐ญ ๐ญ๐๐ฌ๐ญ๐ฌ
Unit test suites not only provide protection against regressions, but they can also highlight design issues therefore it is important to listen to what your tests tell you and make improvements accordingly.
โ๐๐ฉ๐ฆ ๐ข๐ฃ๐ช๐ญ๐ช๐ต๐บ ๐ต๐ฐ ๐ถ๐ฏ๐ช๐ต ๐ต๐ฆ๐ด๐ต ๐ข ๐ฑ๐ช๐ฆ๐ค๐ฆ ๐ฐ๐ง ๐ค๐ฐ๐ฅ๐ฆ ๐ช๐ด ๐ข ๐ฏ๐ช๐ค๐ฆ ๐ญ๐ช๐ต๐ฎ๐ถ๐ด ๐ต๐ฆ๐ด๐ต, ๐ฃ๐ถ๐ต ๐ช๐ต ๐ฐ๐ฏ๐ญ๐บ ๐ธ๐ฐ๐ณ๐ฌ๐ด ๐ช๐ฏ ๐ฐ๐ฏ๐ฆ ๐ฅ๐ช๐ณ๐ฆ๐ค๐ต๐ช๐ฐ๐ฏ. ๐๐ตโ๐ด ๐ข ๐จ๐ฐ๐ฐ๐ฅ ๐ฏ๐ฆ๐จ๐ข๐ต๐ช๐ท๐ฆ ๐ช๐ฏ๐ฅ๐ช๐ค๐ข๐ต๐ฐ๐ณโ๐ช๐ต ๐ฑ๐ฐ๐ช๐ฏ๐ต๐ด ๐ฐ๐ถ๐ต ๐ฑ๐ฐ๐ฐ๐ณ-๐ฒ๐ถ๐ข๐ญ๐ช๐ต๐บ ๐ค๐ฐ๐ฅ๐ฆ ๐ธ๐ช๐ต๐ฉ ๐ณ๐ฆ๐ญ๐ข๐ต๐ช๐ท๐ฆ๐ญ๐บ ๐ฉ๐ช๐จ๐ฉ ๐ข๐ค๐ค๐ถ๐ณ๐ข๐ค๐บ. ๐๐ง ๐บ๐ฐ๐ถ ๐ง๐ช๐ฏ๐ฅ ๐ต๐ฉ๐ข๐ต ๐ค๐ฐ๐ฅ๐ฆ ๐ช๐ด ๐ฉ๐ข๐ณ๐ฅ ๐ต๐ฐ ๐ถ๐ฏ๐ช๐ต ๐ต๐ฆ๐ด๐ต, ๐ช๐ตโ๐ด ๐ข ๐ด๐ต๐ณ๐ฐ๐ฏ๐จ ๐ด๐ช๐จ๐ฏ ๐ต๐ฉ๐ข๐ต ๐ต๐ฉ๐ฆ ๐ค๐ฐ๐ฅ๐ฆ ๐ฏ๐ฆ๐ฆ๐ฅ๐ด ๐ช๐ฎ๐ฑ๐ณ๐ฐ๐ท๐ฆ๐ฎ๐ฆ๐ฏ๐ต.
๐๐ฏ๐ง๐ฐ๐ณ๐ต๐ถ๐ฏ๐ข๐ต๐ฆ๐ญ๐บ, ๐ต๐ฉ๐ฆ ๐ข๐ฃ๐ช๐ญ๐ช๐ต๐บ ๐ต๐ฐ ๐ถ๐ฏ๐ช๐ต ๐ต๐ฆ๐ด๐ต ๐ข ๐ฑ๐ช๐ฆ๐ค๐ฆ ๐ฐ๐ง ๐ค๐ฐ๐ฅ๐ฆ ๐ช๐ด ๐ข ๐ฃ๐ข๐ฅ ๐ฑ๐ฐ๐ด๐ช๐ต๐ช๐ท๐ฆ ๐ช๐ฏ๐ฅ๐ช๐ค๐ข๐ต๐ฐ๐ณ. ๐๐ฉ๐ฆ ๐ง๐ข๐ค๐ต ๐ต๐ฉ๐ข๐ต ๐บ๐ฐ๐ถ ๐ค๐ข๐ฏ ๐ฆ๐ข๐ด๐ช๐ญ๐บ ๐ถ๐ฏ๐ช๐ต ๐ต๐ฆ๐ด๐ต ๐บ๐ฐ๐ถ๐ณ ๐ค๐ฐ๐ฅ๐ฆ ๐ฃ๐ข๐ด๐ฆ ๐ฅ๐ฐ๐ฆ๐ด๐ฏโ๐ต ๐ฏ๐ฆ๐ค๐ฆ๐ด๐ด๐ข๐ณ๐ช๐ญ๐บ ๐ฎ๐ฆ๐ข๐ฏ ๐ช๐ตโ๐ด ๐ฐ๐ง ๐จ๐ฐ๐ฐ๐ฅ ๐ฒ๐ถ๐ข๐ญ๐ช๐ต๐บ. ๐๐ฉ๐ฆ ๐ฑ๐ณ๐ฐ๐ซ๐ฆ๐ค๐ต ๐ค๐ข๐ฏ ๐ฃ๐ฆ ๐ข ๐ฅ๐ช๐ด๐ข๐ด๐ต๐ฆ๐ณ ๐ฆ๐ท๐ฆ๐ฏ ๐ธ๐ฉ๐ฆ๐ฏ ๐ช๐ต ๐ฆ๐น๐ฉ๐ช๐ฃ๐ช๐ต๐ด ๐ข ๐ฉ๐ช๐จ๐ฉ ๐ฅ๐ฆ๐จ๐ณ๐ฆ๐ฆ ๐ฐ๐ง ๐ฅ๐ฆ๐ค๐ฐ๐ถ๐ฑ๐ญ๐ช๐ฏ๐จ.โ โ Validimir Khorikov
Below are a few code design issues that unit tests can highlight:
๐๐จ๐จ ๐ฆ๐๐ง๐ฒ ๐๐จ๐ฅ๐ฅ๐๐๐จ๐ซ๐๐ญ๐จ๐ซ๐ฌ: The complexity and size of the arrange/setup phase of the class under tests hints at a design problem where the class under test simply has too much responsibility, this violates the single responsibility principle.
Before adding a new dependency to your class it is worth pausing and asking ones-self if such an addition will lead to increased responsibility and compromise cohesion, the LCOM metric can help you determine this, another approach may be to adopt a design pattern such as the Command Query Separation Responsibility to create smaller classes.
๐๐ฆ๐ฉ๐ฅ๐๐ฆ๐๐ง๐ญ๐๐ญ๐ข๐จ๐ง ๐๐๐ญ๐๐ข๐ฅ ๐ฅ๐๐๐ค: Performing multiple actions within the "Act" phase of a unit test is a good indication of leaking implementation details as this implies that the client code is required to perform multiple actions to complete a single operation, this is especially true when inconsistencies in calling these actions invalidate the operation in question.
Encapsulating implementation details prevents them from leaking to client code.
๐๐ข๐๐ ๐๐๐๐๐๐ญ๐ฌ: Performing assertions on anything else besides the output of the method under test indicates that executing the method under test yields side effects. Side effects can impact readability and lead to difficult-to-diagnose problems. Side effects can be avoided by making functions mathematical/pure.
Side effects can be unavoidable at times, for example, a side effect of a least recently used cache is the eviction of one member upon the insertion of another.