Sinon async test array is not filled in before push happens
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
When an async test says an array was not filled before push happened, the usual problem is not Sinon itself. The usual problem is that the test made an assertion before the asynchronous work finished. In JavaScript tests, ordering is controlled by await, returned promises, callbacks, or fake timers. If the test does not wait correctly, the array state will look incomplete.
The Real Bug Is Usually Missing Synchronization
Consider this pattern:
A broken test often looks like this:
The assertion runs before the promise settles, so the array is still empty.
Fix It by Awaiting the Async Work
The clean fix is to make the test async and await the function under test.
Now the test waits until the asynchronous push has actually happened.
Return the Promise If You Do Not Use async
Mocha and similar test runners also understand returned promises.
This is equivalent in intent: the test does not finish until the returned promise resolves.
Fake Timers Help Only for Timer-Based Async
If the async ordering depends on setTimeout, setInterval, or similar timer APIs, Sinon fake timers can help drive the scheduled work.
Fake timers do not automatically solve promise ordering by themselves. They only advance timer-based scheduling.
Stub the Right Boundary
Sometimes the array is updated in a callback chain rather than directly after a promise. In those cases, stub the asynchronous dependency at the right level so the function under test still runs its own real logic.
If you stub too much, you may end up testing the stub rather than the array mutation path. If you stub too little, your test becomes flaky because it depends on timing you do not control.
If the code under test chains several promises, await the outermost promise, not an internal helper you happen to know about. Tests should synchronize with public behavior, not with fragile implementation timing.
Common Pitfalls
The biggest mistake is writing a synchronous assertion for asynchronous work. If the function returns a promise, the test must await it or return it.
Another issue is using fake timers for promise-only code that does not actually depend on timers. Advancing the clock will not resolve an unrelated unresolved promise.
People also often forget to restore fake timers, which can leak altered timing behavior into later tests and create very confusing failures.
Finally, do not mix callback-style completion and returned promises carelessly in the same test. Pick one synchronization style and use it consistently.
Summary
- If the array is empty too early, the test is usually asserting before the async work completes.
- Use
awaitor return the promise from the test. - Use Sinon fake timers only when the async behavior depends on timer APIs.
- Stub the dependency boundary carefully so the real mutation path still executes.
- Async test failures about ordering are usually synchronization bugs, not array bugs.

