Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PHPUnit mocked method returns null

I am trying to test the below class using PHPUnit

class stripe extends paymentValidator {
    public $apiKey;

    public function __construct ($apiKey){
        $this->apiKey = $apiKey;
    }

    public function charge($token) {
        try {
            return $this->requestStripe($token);
        } catch(\Stripe\Error\Card $e) {
            echo $e->getMessage();
            return false;
        }
    }

    public function requestStripe($token) {
        // do something        
    }
}

My test scripts is like the below:

class paymentvalidatorTest extends PHPUnit_Framework_TestCase
{
   /**
    * @test
    */
    public function test_stripe() {
        // Create a stub for the SomeClass class.
        $stripe = $this->getMockBuilder(stripe::class)
            ->disableOriginalConstructor()
            ->setMethods(['requestStripe', 'charge'])
            ->getMock();

        $stripe->expects($this->any())
            ->method('requestStripe')
            ->will($this->returnValue('Miaw'));

        $sound = $stripe->charge('token');
        $this->assertEquals('Miaw', $sound);
    }
}

With my test script I was expecting the test double of stripe::charge() method will do exactly as the defined in the original class and the stripe::requestStripe() will return 'Miaw'. Therefore, $stripe->charge('token') should also return 'Miaw'. However, when I run the test I get:

Failed asserting that null matches expected 'Miaw'.

How should I fix this ?

like image 814
Kamrul Khan Avatar asked Jul 22 '16 01:07

Kamrul Khan


1 Answers

Where you're calling setMethods, you're telling PHPUnit that the mock class should mock the behaviour of those methods:

->setMethods(['requestStripe', 'charge'])

In your case it looks like you want to partially mock the class, so that requestStripe() returns Miaw, but you want charge to run its original code - you should just remove charge from the mocked methods:

$stripe = $this->getMockBuilder(stripe::class)
    ->disableOriginalConstructor()
    ->setMethods(['requestStripe'])
    ->getMock();

$stripe->expects($this->once())
    ->method('requestStripe')
    ->will($this->returnValue('Miaw'));

$sound = $stripe->charge('token');
$this->assertEquals('Miaw', $sound);

While you're at it you may as well specify how many times you expect requestStripe() to be called - it's an extra assertion with no extra effort, as using $this->any() doesn't provide you with any added benefit. I've included using $this->once() in the example.

like image 152
scrowler Avatar answered Sep 28 '22 07:09

scrowler