Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

310
Vistas
Why is the Reflection for Memcache::get() different from the doc?

I am trying to add unit tests to a class that uses Memcache as a service to get and store keys on the local memcached daemon.

My problem is that even though the code runs fine, when I try to mock the Memcache class and the get() method is called, I get this kind of error :

ArgumentCountError: Too few arguments to function Mock_Memcache_b25e34cb::get(), 1 passed in /path/to/file.php on line 64 and exactly 3 expected

I suspected a reflection error, so I tried a small script to test it out :

<?php
$class = new ReflectionClass(Memcache::class);
$getMethod = $class->getMethod('get');
$getParams = $getMethod->getParameters();
foreach($getParams as $param) {
    var_dump((string) $param);
}

The output I get is

string(35) "Parameter #0 [ $param0 ]"

string(36) "Parameter #1 [ &$param1 ]"

string(36) "Parameter #2 [ &$param2 ]"

However, the documentation found at the official PHP doc states that the signature should be :

Memcache::get(string $key, int &$flags = ?): string

or

Memcache::get(array $keys, array &$flags = ?): array

How can the discrepancy be explained? Why does my code run fine on production but fails on the UT? Is there a way for me to solve this problem other than creating my own mock class for Memcache? Thanks!

FYI, my current method to get the mock is this :

protected function createMock($originalClassName)
    {
        return $this->getMockBuilder($originalClassName)
                    ->disableOriginalConstructor()
                    ->disableOriginalClone()
                    ->disableArgumentCloning()
                    ->disallowMockingUnknownTypes()
                    ->getMock();
    }

public function existsReturnsTrueOrFalse($value, $expected)
    {
        $memcacheMock = $this->createMock(\Memcache::class);
...
    }
over 4 years ago · Santiago Trujillo
1 Respuestas
Responde la pregunta

0

How can the discrepancy be explained?

Most often this is just that the documentation is not up-to-date with the extension.

Another explanation can be an error with the libraries reflection.

Seeing the output from the reflection, I'd say the docs are more up to date than the reflection.

Why does my code run fine on production but fails on the UT?

The difference between production and the test run of your unit tests for your question is the creation of the mock: On production you don't create the mock and therefore it does not fail.

Is there a way for me to solve this problem other than creating my own mock class for Memcache?

Actually creating your own mock class does not sound as a bad idea. However you might consider thinking a step further:

Right now the production code has the Memcache class as a dependency. Your tests already show you, that the interface of it is unstable, the dependency refuses the test (with your standard tooling like the mocks).

For reasons like this and others, it is often recommended to wrap third-party libraries. It's perhaps an edge-case here as this is related to a PHP extension that is likely not that volatile, but perhaps the wrapping gives you more room for development, testing and maintaining already.

You can extract the part of the public interface of the Memcache class you make use of into an interface itself, e.g. MemcacheInterface. Then you can create a light-weight wrapping-class that implements the interface and under-the-hood delegates the method calls to a Memcache instance.

You then replace the Memcache object in the production code with the object of your wrapper and type-hints of Memcache with your MemcacheInterface interface.

In tests you create the mock from the interface.

This will

  1. document every method and parameter in use (you do this at the interface).
  2. allow to create mocks in Phpunit as you create them from the (unambiguous) interface.
  3. interface access to the third-party library at a central place by the new wrapper class - even in production.
  4. allows you in the future to switch to a different memcache third-party library in your application (but you must not, I mention it for brevity).
over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda