php - Mocking class parameter that returns a mock in Laravel 5.1 -
i new unit testing , trying test controller method in laravel 5.1 , mockery.
i trying test registeremail method wrote, below
<?php namespace app\http\controllers; use illuminate\http\request; use response; use mailchimp; use validator; /** * class apicontroller * @package app\http\controllers */ class apicontroller extends controller { protected $mailchimplistid = null; protected $mailchimp = null; public function __construct(mailchimp $mailchimp) { $this->mailchimp = $mailchimp; $this->mailchimplistid = env('mailchimp_list_id'); } /** * @param request $request * @return \illuminate\http\jsonresponse */ public function registeremail(request $request) { $this->validate($request, [ 'email' => 'required|email', ]); $email = $request->get('email'); try { $subscribed = $this->mailchimp->lists->subscribe($this->mailchimplistid, [ 'email' => $email ]); //var_dump($subscribed); } catch (\mailchimp_list_alreadysubscribed $e) { return response::json([ 'mailchimplistalreadysubscribed' => $e->getmessage() ], 422); } catch (\mailchimp_error $e) { return response::json([ 'mailchimperror' => $e->getmessage() ], 422); } return response::json([ 'success' => true ]); } }
i attempting mock mailchimp object work in situation. far, test looks follows:
<?php use illuminate\foundation\testing\withoutmiddleware; use illuminate\foundation\testing\databasemigrations; use illuminate\foundation\testing\databasetransactions; class homeroutetest extends testcase { use withoutmiddleware; public function testmailchimpreturnsduplicate() { $listmock = mockery::mock('mailchimp_lists') ->shouldreceive('subscribe') ->once() ->andthrow(\mailchimp_list_alreadysubscribed::class); $mailchimp = mockery::mock('mailchimp')->lists = $listmock; $this->post('/api/register-email', ['email'=>'duplicate@email.com'])->assertjson( '{"mailchimplistalreadysubscribed": "duplicate@email.com subscribed list."}' ); } }
i have phpunit returning failed test, 1) homeroutetest::testmailchimpreturnsduplicate mockery\exception\invalidcountexception: method subscribe() mockery_0_mailchimp_lists should called 1 times called 0 times.
also, if assert status code 422, phpunit reports receiving status code 200.
it works fine when test manually, imagine overlooking easy, guidance appreciated. thank you!
mockery expect class being passed in controller mock object can see here in docs:
class temperature { public function __construct($service) { $this->_service = $service; } }
unit test
$service = m::mock('service'); $service->shouldreceive('readtemp')->times(3)->andreturn(10, 12, 14); $temperature = new temperature($service);
in laravel ioc autoloads classes , injects them, since not autoloading mailchimp_lists
class won't mock object. mailchimp requiring class atop it's main class require_once 'mailchimp/lists.php';
then mailchimp loading class automatically in constructor
$this->lists = new mailchimp_lists($this);
i don't think you'll able mock class out of box. since there isn't away pass in mock object mailchimp class , have replace instance of real mailchimp_lists
i see trying overwrite lists member variable new mock before call controller. lists object being replaced mocked one? try seeing classes in controller when gets loaded , see if in fact getting overridden.
Comments
Post a Comment