Tests Should Buy Confidence, Not Become the Feature
DEV Community

Tests Should Buy Confidence, Not Become the Feature

While implementing the Job Opportunity creation workflow in my Candidate Tracker, I reached an uncomfortable point: the application-service tests felt harder to understand than the feature itself.

The production workflow was small:

  • Validate and normalize the submitted input.
  • Confirm that the selected Company exists.
  • Create the Job Opportunity.

The tests introduced much more vocabulary and setup: fixtures, fakes, spies, mocks, controlled failures, and assertions that certain repository methods were never called. That complexity is not automatically a problem. A test must construct the world in which a behavior runs. However, it made me reconsider what each test was actually buying.

The tests I kept

I kept three application-service cases:

  • valid input is normalized and created;
  • invalid input stops before persistence;
  • a missing Company does not create an orphan opportunity.

These cases protect business decisions. If any of them breaks, the application can accept invalid data or violate an important relationship.

The tests I did not add

The service also forwards failures returned by repositories. I could mock every repository method and test every forwarding branch, but those tests would mostly prove that:

if (!result.success) return result; {data-source-line="157"}

returns the same result it received. That behavior is already constrained by TypeScript, while real PostgreSQL integration tests verify persistence behavior. The complete browser workflow was also checked manually. Adding more mocks would increase the test count, but not necessarily my confidence.

Choosing the right testing level

My current rule is:

  • unit-test business rules and meaningful decisions;
  • integration-test actual persistence behavior;
  • verify the complete user workflow;
  • add regression tests when real bugs reveal a missing case;
  • do not optimize for test count or branch coverage alone.

This is not an argument against testing. It is an argument for making every test justify its maintenance cost. Tests should reduce the fear of changing code. When the setup becomes harder to understand than the protected behavior, the testing level or scope may need simplification-not necessarily the feature.

Comments

No comments yet. Start the discussion.