Question

I have this class:

class PagSeguro {

    public function pay()
    {
        if ( ! $this->checkAllData() )
        {
            return false;
        }

        return $this->buildPaymentURL();
    }

    private function checkAllData()
    {
        return true;
    }

    private function buildPaymentURL()
    {
        echo "not cool!\n\n";

        return true;
    }

}

And this test for it:

public function testPagSeguroPaymentData()
{
    $m = m::mock('PagSeguro[buildPaymentURL]');

    $m->shouldReceive('buildPaymentURL')
        ->once()
        ->andReturn('http://');

    $this->assertEquals($m->pay(), 'http://');
}

If I var_dump($m) I see the mocked method:

    'buildPaymentURL' =>
    class Mockery\ExpectationDirector#1507 (5) {
      protected $_name =>
      string(15) "buildPaymentURL"
      protected $_mock =>
              ...

      protected $_expectations =>
      array(1) {
        ...
      }
      protected $_expectedOrder =>
      NULL
      protected $_defaults =>
      array(0) {
        ...
      }
    }
  }

But when the test executes, it's calling not the mocked one but the real one. Unless I rename it

private function buildPaymentURL_RENAMED() {}

And then I get a green.

Anyone can show me the right way of doing those partial mocks using Mockery?

Was it helpful?

Solution

I think you cannot have that method be private, because the very time you enter the code of your real object, any call to $this->buildPaymentURL MUST end up in that real private method.

Make it protected. That way, the mock can extend your class and overwrite the function.

On the other hand, I always have a bit of a bad feeling if there is a need for such partial mocks. They are most likely a sign of bad design. It seems that this private method should rather be contained in an object of its own that is dealing with URL creation exclusively (and can be tested seperately), and this class you are testing now should only get a complete mock of that new class injected.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top