mercredi 15 juillet 2015

How to test methods are called when their API is using chaining

I'm using Omnipay to handle my payment gateways, but I've abstracted this out to another few classes to handle a lot of the hassle.

The idea being I can do this:

Transaction::payment($product)
    ->forUser($user)
    ->saveForFutureUse()
    ->complete();

My main issue is that when trying to test that a specific method from Omnipay is called, I have to mock the Omnipay class, but, because it's a chaining API and it returns instances of different objects, dependant on what method you call, for example:

$response = $this->gateway->createCard($this->paymentDetails)->send();

My issue is that I can detect when createCard is called by stubbing $this->gateway, but then the call to send is apparently undefined.

I'm currently attempting to do the following to test that the methods are called:

public function its_a_test(Class $user, Gateway $gateway, PurchaseRequest $paymentRequest)
{
    $product= new Product;
    $this->beConstructedWith($product);

    $gateway->createCard(['card' => (new MockedCreditCard)->make() ])->shouldBeCalled();
    $this->gateway = $gateway;

    $this->forUser($user);

    // Make sure it creates a new token
    $this->withCard( (new MockedCreditCard)->make() );
    $this->saveForFutureUse();
    $this->saveTransactionForFuturePayments->shouldBe(true);

    $user->save()->shouldBeCalled();
    $this->complete();
}

Any help on this would be a HUGE help!

Aucun commentaire:

Enregistrer un commentaire