Back to News & Insights
JavaScript August 17, 2026 · 5 min read

Upgrade your Test Suite with fn-monitor

Combining Vitest with fn-monitor to assert not just what your functions return, but the work they actually do.

Upgrade your Test Suite with fn-monitor

Modern JavaScript testing focuses heavily on testing public outputs and user behavior rather than chasing line-by-line or branch-by-branch coverage. This is because tests that check final outputs survive when you rewrite internal logic or change how a loop works, and they already catch the majority of regressions.

Despite this, if you write complex financial calculations, security rules, or state machines where an unhandled condition cannot be tolerated, then a green test on the final value is not the whole story. The same return value can be produced by two different executions — one correct, and one that silently skipped a critical step — and an assertion on the output alone cannot tell them apart. In those domains, you need to verify not just what the function returned, but the work it performed to get there.

That is the gap this article closes. We will combine Vitest with fn-monitor — a function-level execution monitor — and upgrade a suite from asserting outputs to asserting internal behavior: which calls ran, which were skipped, and which paths were taken.

The setup is deliberately minimal: two dependencies, one source file, one test file, and a handful of config lines. Create a folder (we'll call it vitest-with-monitor) with this structure:

We're going to test a progressive tax calculator. It applies different rates across income brackets, but there's a compliance requirement: high-income earners must trigger an audit. If that audit call gets accidentally removed during a refactor, the tax calculation still returns the correct number — but now you have a compliance violation.

First, we write the standard blackbox test. It looks perfectly fine and passes with the correct code, but it only asserts that the calculation is correct.

Next, we write the test using fn-monitor. We don't just check the return value; we check the AST to assert that triggerHighIncomeAudit was actually called during execution.

Because fn-monitor works by running your functions through a JS-in-JS interpreter, it loses access to its lexical scope upon wrapping. The captures property gives the interpreter access to triggerHighIncomeAudit so it can resolve the call. Without it, the interpreter would throw a ReferenceError when calculateTax tries to call it.

Notice that we didn't have to modify triggerHighIncomeAudit, inject a mock, or use vi.fn() to track the call. fn-monitor observes the execution non-invasively.

Six months later, a well-meaning developer refactors calculateTax to clean up the math. They accidentally delete the audit call.

When we run the tests, we will see that it is only the second test that catches the regression and fails:

The upgraded test caught a compliance violation that the first one missed — but we paid for it with extra code and execution overhead. That's the tradeoff: internal behavior assertions are more expensive but catch a different class of bugs.

Use them when: Silent failures are unacceptable — compliance rules, financial calculations, security checks Side effects matter — logging, analytics, cache invalidation, audit trails Output alone doesn't tell the whole story — the same return value could come from correct or incorrect internal work

For most tests, output assertions are enough. They're fast, they survive refactors, and they catch the majority of regressions. But for the 5% of your code where a green test on the wrong behavior is a real problem, fn-monitor gives you the observability to assert on the work, not just the output.

This article covered the most common use case: observing internal behavior. fn-monitor has two other powerful patterns worth exploring: Execution Timeouts — govern how long a function can run before it's forcibly stopped. Useful for preventing infinite loops and enforcing performance budgets. AST Mutation — rewrite function behavior at the AST level. Useful for advanced mocking and testing scenarios where you need to intercept and modify code before it runs.

The code for this article is available in the vitest-with-monitor repository. Clone it, run npm install and npm test, and see the difference between the blackbox and upgraded tests yourself.

If you're interested in using fn-monitor in your own projects, check out the main repository for installation instructions and full documentation.

Want to discuss this further?

Book a free strategy call with our team to see how these insights apply to your specific business goals.

Book a consultation