Looking deeper into this, I'm not sure it's even possible, which is a shame because I'm trying to learn TDD.
I would like to test my model with Billable
being created and subscribed to a plan.
/** @test */
public function an_account_can_subscribe_to_a_plan() {
$account = factory("App\Account")->create();
Stripe::setApiKey('key');
$paymentMethod = PaymentMethod::create([
'type' => 'card',
'card' => [
'number' => '4242424242424242',
'exp_month' => '2',
'exp_year' => '2021',
'cvc' => '314'
]
]);
$subscription = $account->newSubscription('default', 'starter')->create($paymentMethod);
$this->assertTrue( $subscription->valid() );
}
The Laravel Cashier docs show how to send a token via Stripe.js, but that doesn't work for Unit Testing.
I've tried to include the Stripe library directly and create a PaymentMethod
object, but this also requires me set an API key manually. Now the error I'm getting is that I have to verify my phone number to send raw credit card numbers to the stripe API.
I'm hoping there's a better way. How can I use Laravel Cashier in a TDD way and mock up fake subscriptions with fake payment methods?
Stripe provides not only test card numbers, but tokens and payment method's.
https://stripe.com/docs/testing#cards
Click the PaymentMethods tab. The value (for example pm_card_visa
) can be used directly on the server-side in your tests without the need of front-end payment-intent implementation.
This is an example of a feature test I have:
/**
* @test
*/
public function a_user_can_subscribe_to_a_paid_plan()
{
$this->actingAs($this->user);
$this->setUpBilling();
$enterprise = Plan::where('name', 'Enterprise')->first()->stripe_plan_id;
$response = $this->post(route('paywall.payment'), [
'payment_method' => 'pm_card_visa',
'stripe_plan_id' => $enterprise
])
->assertSessionDoesntHaveErrors()
->assertRedirect();
}
Your tests may vary, but you can make a normal request to your billing controller with these test payment methods and it goes through just as it would if you do it on the front-end.