Skip to content

Unit tests can't mock final MoneiApiClient — extract interface #2

@alexandresaiz

Description

@alexandresaiz

Problem

`phpunit` fails on main across all PHP/Sylius matrix combinations with 10 errors:

```
PHPUnit\Framework\MockObject\Generator\ClassIsFinalException:
Class "Monei\SyliusPlugin\Client\MoneiApiClient" is declared "final" and cannot be doubled
```

The affected tests are `tests/Unit/Action/StatusActionTest.php` and `tests/Unit/Action/RefundActionTest.php`, which call `$this->createMock(MoneiApiClient::class)`. PHPUnit 10 enforces that `final` classes cannot be doubled.

Static analysis is also red — PHPStan reports 4 errors including `Cannot call method jsonSerialize() on class-string|object`.

Design intent vs. current state

The class docblock states:

Isolates the SDK from Payum's action layer so that:

  • Actions depend on a mockable interface, not a concrete SDK class.

But the class is a concrete `final class` with no interface. The intent was never implemented.

Recommended fix

  1. Extract `MoneiApiClientInterface` covering the methods the Payum actions call (`createPayment`, `getPayment`, `refundPayment`, etc.).
  2. Have `MoneiApiClient implements MoneiApiClientInterface`.
  3. Typehint Payum actions against `MoneiApiClientInterface`, not the concrete class.
  4. Update tests to `createMock(MoneiApiClientInterface::class)` — then `MoneiApiClient` can stay `final` as originally intended.
  5. Fix the 4 PHPStan errors separately (mostly narrowing `class-string|object` unions).

Why not quick-patch

Removing `final` would unblock mocks but directly contradicts the documented design. Not a sustainable fix.

Context

CI has been red since the initial commit on 2026-04-11. Plugin runtime behavior is unaffected — only test-time failures.

Last failing run: https://github.com/MONEI/SyliusMoneiPlugin/actions

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions