php - How can I test the type of something generated in my phpspec test? -
for example:
test code
function it_records_last_checked() { $this->getwrappedobject()->setservicelocator( $this->getservicelocator() ); $this->isavailable( 'google.com' )->shouldreturn( false ); /** @var url $last */ $last = $this->getlastchecked(); $last->shoudhavetype( url::class ); $last->host->registrabledomain->shouldbelike('google.com'); }
the spec wraps object code this:
namespace application\service; use application\exception\domaininvalidexception; use application\model\whois; use pdp\uri\url; use zend\servicemanager\servicelocatorawareinterface; use zend\servicemanager\servicelocatorawaretrait; use application\exception\domainrequiredexception; class domainservice implements servicelocatorawareinterface{ use servicelocatorawaretrait; /** @var url */ protected $last_checked; /** * @return url */ public function getlastchecked() { return $this->last_checked; } /** * @param url $last_checked */ public function setlastchecked( $last_checked ) { $this->last_checked = $last_checked; } /** * use available configuration determine if domain available * @param $domain * @return bool * @throws domainrequiredexception * @throws \exception */ public function isavailable($domain) { if( !$domain ) throw new domainrequiredexception(); $pslmanager = new \pdp\publicsuffixlistmanager(); $parser = new \pdp\parser($pslmanager->getlist()); $host = 'http://' . $domain; if( !$parser->issuffixvalid( $host ) ) throw new domaininvalidexception(); $this->last_checked = $parser->parseurl($host); $whois = new whois($this->last_checked->host->registerabledomain); return $whois->isavailable(); } }
the service sets last_checked member type want test example. seems doesn't return wrapped object, returns actual pdp\uri\url instance.
what's rule in writing tests, ensure wrapped objects (subject)?
thanks!
the difficulty finding in testing logic phpspec trying push different design. test validating , reliant on behaviour/structure of 6/7 other objects making more of integration test rather unit test (doing intentionally difficult in phpspec)
i have highlighted of these dependencies:
<?php public function isavailable($domain) { // pdp\parser instantiation , configuration $pslmanager = new \pdp\publicsuffixlistmanager(); $parser = new \pdp\parser($pslmanager->getlist()); // validation , parsing of $domain url object if( !$domain ) { throw new domainrequiredexception(); } $host = 'http://' . $domain; if( !$parser->issuffixvalid( $host ) ) { throw new domaininvalidexception(); } $this->last_checked = $parser->parseurl($host); // "isavailable" check // depends on `pdp\uri\url\host` (in addition whois , `pdp\uri\url` $whois = new whois($this->last_checked->host->registerabledomain); return $whois->isavailable(); }
by moving configuration/instantiation of pdp classes, , splitting validation/parsing logic whois
check arrive @ bit more testable (but less convenient api)
public function __construct(\pdp\parser $parser) { $this->parser = $parser; } public function parsedomain($domain) { if( !$domain ) { throw new domainrequiredexception(); } $host = 'http://' . $domain; if( !$parser->issuffixvalid( $host ) ) throw new domaininvalidexception(); return $parser->parseurl($host); } public function isavailable(url $domain) { $whois = new whois($domain->host->registerabledomain); return $whois->isavailable(); }
but making whois capable of checking if url
object available, , injecting testing gets easier
class domainparser { // pdp\parser should registered service public function __construct(\pdp\parser $parser) { $this->parser = $parser; } public function parsedomain($domain) { if( !$domain ) { throw new domainrequiredexception(); } $host = 'http://' . $domain; if( !$parser->issuffixvalid( $host ) ) throw new domaininvalidexception(); return $parser->parseurl($host); } } class whois { public function isurlavailable(url $url) { // whois logic } } class domainservice { public function __construct(domainparser $parser, whois $whois) { $this->parser = $parser; $this->whois = $whois; } public function isavailable($domain) { $url = $this->parser->parsedomain($domain); $this->last_checked = $url; return $this->whois->isurlavailable($url); } }
with these 3 classes, easy unit test domainservice
, domainparser
, whois
can mocked , tested using strategy (assuming communicates third party system)
e.g.
function let(domainparser $parser, whois $whois) { $this->beconstructedwith($parser, $whois); } function it_shows_a_domain_is_available( domainparser $parser, whois $whois, url $url ) { $parser->parsedomain('http://test.com')->willreturn($url); $whois->isurlavailable($url)->willreturn(true); $this->isavailable('http://test.com')->shouldreturn(true); } function it_records_last_checked( domainparser $parser, whois $whois, url $url ) { $parser->parsedomain('http://test.com')->willreturn($url); $whois->isurlavailable($url)->willreturn(true); $this->isavailable('http://test.com'); // note don't validate properties on url, // responsibility of tests domainparser , url object $this->getlastchecked()->shouldreturn($url); }
Comments
Post a Comment