7

In my application code, I've got a method_exists check to authorize some hooking in a create process:

// Note: $myClass is implementing a ListItemFactory interface.

if ($isCreate) {
  $methodName = "create{$attr}ListItem";

  if (method_exists($myClass, $methodName)) {
    $item = $myClass->$methodName();
  } else {
    [...]
  }
}

I'm trying to test this code, mocking $myClass and checking if $methodName is in fact called. Here's how I wrote the test:

/** @test */
function specific_create_method_is_called()
{
  $factory = Mockery::mock(ListItemFactory::class)->makePartial();
  $factory->shouldReceive("createCommentsListItem")->once();
  [...]
}

But this isn't working, because method_exists is not defined in the mock. I'm fairly new to mock stuff, so maybe there's an obvious way to manage this problem, like "stubbing" the wanted function, but I wasn't able to find the way...

Thanks in advance for any help.

Philippe
  • 668
  • 8
  • 17
  • The ListItemFactory source would be great to see. – l-x Nov 30 '15 at 14:38
  • was just solving very similar stuff, check out http://stackoverflow.com/questions/37927273/how-to-unit-test-a-php-method-exists/37928161#37928161 this might help you – user3350906 Jun 20 '16 at 17:41
  • This is what helped me: https://stackoverflow.com/a/46922330/470749 – Ryan Feb 23 '19 at 19:13

1 Answers1

0

Create a small testing class and mock it partially. Define in the scope of your test class:

class MyClass implements ListItemFactory {
  public function createCommentsListItem() { } 
}

Then, in your test function:

/** @test */
function specific_create_method_is_called() 
{
  $myClass = m::mock(MyClass::class)->makePartial();

  $myClass->shouldReceive('createCommentsListItem')->once();

  // method_exists($myClass, 'createCommentsListItem')
  //   returns true now
}

(in this example: use Mockery as m;)

Tom
  • 3,281
  • 26
  • 33