Skip to content

Thoughts on atLeast(), atLeastOnce() and atMost() after the refined Stub/Mock distinction #6483

@laloona

Description

@laloona

This is not a feature request, but a design / guidance discussion.
With PHPUnit 12.5 the conceptual distinction between stubs and mocks has been clarified further, and in addition, any() is already scheduled for removal in PHPUnit 14 according to the roadmap.

Given this direction, I was wondering how atLeast(), atLeastOnce() and atMost() fit into this refined model of test doubles.

I might be overthinking this, but from a strict testing perspective (especially when considering mutation testing), non-exact invocation expectations can feel slightly at odds with the goal of making test intent explicit:
if the exact number of invocations is not relevant, the double often behaves more like a stub; if it is relevant, exactly() expresses the contract more clearly.

At the same time, there are clearly cases where minimum or maximum invocation counts are meaningful parts of a contract (for example retries or “must not happen more than once” constraints).

I am curious about your perspective on whether:

  • these matchers should simply remain as pragmatic tools,
  • their intended use could be clarified or more strongly guided in the documentation, or
  • any further tightening (similar to the direction taken with any()) would make sense in the long run.

My main interest is in understanding how you see the role of these matchers in PHPUnit’s ongoing effort to make test intent more explicit.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions