laravel - Am I mock too much or doing TDD and unit testing the right way? -
i'm developing web application using laravel , web app has connect internal service. choose tdd in project , i'm facing problem dependencies mock.
in registercontroller
, allow user login , upgrade account type, see code below:
public function loginforupgradeaccount() { $data = input::only('email', 'hashedpassword'); if (!empty($data['email']) && !empty($data['hashedpassword'])) { $email = $data['email']; $hashedpassword = $data['hashedpassword']; $login = $this->createloginserviceconnector(); $token = $login->withemailandhashedpassword($email, $hashedpassword); if ($token) { $profile = $this->createprofileserviceconnector($token); if ($profile->getdata()['secret_code'] != session::get('thirdpartydata')['secret_code']) { return $this->builderrorjsonresponse('upgd-002', 'secretcode not match third party', 400); } else { if ($profile->getdata()['profile_type'] == 'consumer') return $this->builderrorjsonresponse('upgd-003', 'profile type consumer', 400); else //has call internal upgrade api } } } return $this->builderrorjsonresponse('upgd-001', 'wrong email or password', 400); } public function createloginserviceconnector() { return new login(apiinvokerfactory::createapijsoninvoker()); } public function createprofileserviceconnector($token) { return new profile(apiinvokerfactory::createapijsoninvoker(), $token); }
and example of test code below:
public function test_loginforupgrade_must_return_error_code_upgd_002_when_secret_code_not_match_with_third_party_data() { $data = array('email' => 'correct@example.com', 'hashedpassword' => '123333'); $profiledata = array( 'secret_code' => 'abcdefg', ); session::put('thirdpartydata', array('secret_code' => 'hijklmnop')); input::shouldreceive('only') ->with('email', 'hashedpassword') ->andreturn($data); $login = mockery::mock('login'); /** @var $login registercontroller|\mockery\mockinterface */ $ctrl = mockery::mock('registercontroller'); $ctrl->shoulddefermissing(); /** @var profile||mockinterface $profile */ $profile = mockery::mock('profile'); $ctrl->shouldreceive('createloginserviceconnector') ->andreturn($login); $login->shouldreceive('withemailandhashedpassword') ->with($data['email'], $data['hashedpassword']) ->andreturn('correcttokenlogin'); $ctrl->shouldreceive('createprofileserviceconnector') ->with('correct_tokenlogin') ->andreturn($profile); $profile->shouldreceive('getdata') ->andreturn($profiledata); $result = $ctrl->loginforupgrade(); $response = json_decode($result->getcontent(), true); $this->assertequals('upgd-002', $response['errorcode']); }
this 1 example test case , have same code other scenario in 1 controller action wrong email or password , profile type consumer , more.
i think hard maintain messy test code , if someday our flow upgrade changed or require more condition upgrade broke of test , have delete , rewrite again.
am unit testing , tdd correctly?
please suggest me right way.
am unit testing , tdd correctly?
doing tdd wrong hard. tdd process. write test write code fulfill test's requirements. simple.
on other hand, doing software design wrong very easy. sticking solid principles, keeping code loosely coupled, avoiding common anti-patterns , anticipating upcoming changes (software , requirements change time) very, hard. requires constant, non-trivial , non-obvious decision making.
unit tests, being first consumers of code first highlight design issues. namely, complex, hard write , fragile. symptoms lead single cause -- incorrect design decisions.
how can code improved mitigate problems? take closer at:
loginforupgradeaccount
-- logging in specific account upgrade? or more general process? can users log in , not do account upgrade? may first extraction point (ie.upgradeaccount(login)
orapplicationgateway->login(user)
)$this->builderrorjsonresponse
-- upgrading account responsible json response generation? best fitted parameterized factory of sort (errorresponsefactory->createforaccountupgrade(profiledata)
)
those kind of decisions you'll have make. unit test spotting wrong decisions early.
Comments
Post a Comment