skip to Main Content

Assume there is a method

public function updateTimestamp($sessionId, $data)
{
    return $this->memcached->touch($sessionId, time() + $this->ttl);
}

that I’d like to test. Infection changes the + in time() + $this->ttl to - and all my tests are still passing. So I’d like to make a test that will mock Memcached’s touch in it and will conditionally return true/false basing on the second argument passed to it.

So doing something like:

    // $ttl is set;
    $memcachedMock
        ->touch(
            'sessionId',
            $certainValuePassedToTouch
        )
        ->willReturn(
            $certainValuePassedToTouch >= time() + $ttl 
                ? true 
                : false
        )
        ;

There are two problems now:

  1. I don’t know how to make such a condition for an arbitrary integer parameter passed to the method being mocked
  2. basing on time() seems to be very unreliable, so how can I reliably test it if time() is used in the method itself?

3

Answers


  1. Maybe can you take a look on this tools :

    Based on PHP’s namespace fallback policy (https://www.php.net/manual/en/language.namespaces.fallback.php), it allow to mock php native functions like time(), date(), etc.

    Login or Signup to reply.
  2. For arbitrary parameters you could take a look at Faker library. It generates arbitrary fake data for you.

    Login or Signup to reply.
  3. You can mock the time() function to return 0 and the return value of the touch() method will depend solely on the $ttl value. For the first, there are suggestions in other answers, and the second can be archived with returnCallback().

    $memcachedMock
        ->method('touch')
        ->will($this->returnCallback(function ($key, $val) {
            return $val > 0;
        }));
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search