Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Let tested using a mock with PHPUnit
Search
halt
March 30, 2015
4
2.8k
Let tested using a mock with PHPUnit
PHPUnitなんて当たり前に知ってるし、ユニットテストだってちょっとは書いたことある。
でも実務では面倒くさくて結局書けない。そんなあなたのためにモックの具体的な使い方を紹介した資料です。
halt
March 30, 2015
Tweet
Share
More Decks by halt
See All by halt
transaction and lock for beginner
ha1t
1
2.2k
Featured
See All Featured
How To Stay Up To Date on Web Technology
chriscoyier
786
250k
The Pragmatic Product Professional
lauravandoore
31
6.2k
KATA
mclloyd
27
13k
10 Git Anti Patterns You Should be Aware of
lemiorhan
653
59k
Bash Introduction
62gerente
608
210k
Designing Experiences People Love
moore
138
23k
Optimising Largest Contentful Paint
csswizardry
31
2.8k
Writing Fast Ruby
sferik
625
60k
Evolution of real-time – Irina Nazarova, EuRuKo, 2024
irinanazarova
2
210
Designing the Hi-DPI Web
ddemaree
279
34k
実際に使うSQLの書き方 徹底解説 / pgcon21j-tutorial
soudai
167
48k
Typedesign – Prime Four
hannesfritz
39
2.3k
Transcript
࠶ֶश PHPUnitͰϞοΫΛ ͬͯςετ͠Α͏ 2015-03-30 ୈ88ճ PHPษڧձ ࠇҪय़ਓ
ςετॻ͍ͯ·͔͢ʁ
Ғ͍ਓ͜͏͍͏Θ͚Ͱ͕͢
࣮ࡍ໘͍͘͞
ςετͷॏཁੑΘ͔͍ͬͯ Δ͠ɺϢχοτςετͱ͔ॻ ͍ͯ͋ΔͱͳΜ͔ΧοίΠΠ
None
None
ςετΛॻ͘ͱCIͰ͖Δ
Βͳ͍ΑΓͬͨ΄͏͕ ઈରྑ͍
Ͱ໘͍͘͞
ͳ͔ͥʁ
ͱ͍͏͜ͱΛࠓߟ͑ͯΈ ·͠ΐ͏ɻ
جຊͷ͓͞Β͍
PHPUnitΛ͓͏
PHPUnitΛ͓͏ • ݱࡏͬͱϙϐϡϥʔͳPHPʹ͓͚ΔϢχοτ ςετϥΠϒϥϦ • Θ͕͠ए͍ࠒ simpletest ͱ͔ lime ͱ͔ܹ͋ͬͯ
͍͠ઓ͍Λ܁Γ͓͛ͯͬͯͷ͎ΰϗΰϗ… • ࠓͱʹ͔͘ίϨΛ֮͑ΕOK(͔ͨͩ͠ͳΓԞ ͕ਂ͍)
Install࣮؆୯ • wget https://phar.phpunit.de/phpunit.phar • chmod 775 phpunit.phar • mv
phpunit.phar $HOME/bin/phpunit http://project-p.jp/halt/?p=1882
ςετͷͻͳܗΛ༻ҙ࣮ͯ͠ߦ class Member { } class MemberTest extends PHPUnit_Framework_TestCase {
public function test_createInstance() { $member = new Member(); $this->assertTrue($member instanceof Member); } }
php-timeͷ߹ https://github.com/ttsuruoka/php-time
/** * ݱࡏ͕࣌ؒ༩͑ΒΕͨ࣌ؒΑΓલ͔Ͳ͏͔ * * Ҿͱͯ͠null ͕༩͑ΒΕͨͱ͖ɺfalse Λฦ͠·͢ɻ * @param
$a unixtimeΛද͢ɺ·ͨͱͯ͠ղऍՄ ೳͳจࣈྻ * @return boolean ݱࡏ͕࣌ؒ༩͑ΒΕͨ࣌ؒΑΓલͷͱ͖ trueɺͦΕҎ֎ͷͱ͖ false */ public static function before($a) { if (is_null($a)) { return false; } $a = is_int($a) ? $a : strtotime($a, self::$time); return self::$time < $a; }
public function test_before() { Time::set(strtotime('2011-11-01 15:00:00')); $this->assertEquals(Time::before(null), false); $this->assertEquals('2011-11-01 15:00:00',
Time::now()); $this->assertTrue(Time::before('2011-11-01 16:00:00')); $this->assertTrue(Time::before('2011-11-01 15:00:01')); $this->assertFalse(Time::before('2011-11-01 15:00:00')); $this->assertFalse(Time::before('2011-11-01 14:59:59')); }
؆୯ʂ ΈΜͳΖ͏ʂ
͓͠·͍
phpunit.phar ͬͨΓ assert ϝιουͬͯ ݕূͨ͠Γɺ phpunit.xml Ͱςετέʔεࢦ ఆͨ͠Γɺ MVC Ͱ͍ͬͨΒ
Model ͚ͩΔ ͱ͍ͩͿҧ͏ͱ͔ fixture ॻ͘ͱ͔ xdebug ೖΕΔͱΧόϨοδͱΕΔͱ͔ͱ͔ͱ͔… " શ෦ͬͯΔʂ ͚Ͳॻ͔ͳ͍ΜͰ͢ʂ
ͳ͔ͥʁ
ݱ࣮ͷ࣮ͬͱ໘͍͘͞ • AͷதͰBΛࢀরͯ͠B͕CΛࢀর͍ͯ͠Δ • ֎෦ͱͷ௨৴Λߦͳ͏ • Ϣʔβʔ໊ύεϫʔυ͕ඞཁ • ؔ࿈σʔλ͕ͳ͍ͱಈ͔ͳ͍ •
ݶఆ͞Εͨڥ͡Όͳ͍ͱಈ͔ͳ͍ • ͳͲͳͲ…
࣮ࡍͬͱ໘͍͘͞ Internet DB Library Local
ϞοΫΛ͏ͱ͍͍ײ͡ʹς ετʹઐ೦Ͱ͖Δ
ϞοΫͱ • ϞοΫ = ܕ = ֎ݟͷݕ౼ͳͲͷͨΊʹ࡞Β ΕΔݪܕ • ࣮ࡍͷΦϒδΣΫτΛஔ͖͑ͯɺςετ༻
ʹઃఆͨ͠Λฦ͢ͱ͖ʹ͏
ͯ͢ΛίϯτϩʔϧԼʹ͓͘ Mock Library Local
ԿΛݴ͍ͬͯΔͷ͔?
0͔Βॻ͚ͱݴΘΕΔͱ ໘͚ͩͲ ࣄྫ͕͋ΕίϐϖͰઓ͑Δ
InternetΞΫηε Λ ϞοΫͰ༻͢Δ
Services_Photozouͷ߹ https://github.com/ha1t/php-Services_Photozou
public function nop() { $xml = $this->callMethod("nop"); if (strpos($xml, 'stat="ok"')
!== false) { return true; } else { return false; } } $this->callMethodͰAPI௨৴͕͠ΔͷͰ ωοτϫʔΫ͕ͭͳ͕ͬͯͳ͍ͱಈ͔ͳ͍
public function testNop() { $response = <<<EOD <?xml version="1.0" encoding="UTF-8"
?> <rsp stat="ok"> <info><user_id>1111</user_id></info> </rsp> EOD; $photozou = new Services_Photozou($this- >user, $this->password); $this->injectMock($photozou, $response); $this->assertTrue($photozou->nop()); }
public function injectMock(Services_Photozou $photozou, $response) { $mock = new \GuzzleHttp\Subscriber
\Mock($response); $class = new ReflectionClass(‘Services_Photozou'); $property = $class->getProperty(‘client'); $property->setAccessible(true); $client = $property->getValue($photozou); $client->getEmitter()->attach($mock); } ͬ͘͟Γ͜Μͳײ͡ͰͰ͖Δ
Guzzle->getEmitter()- >attach() • ϞμϯͳPHPͰͷఆ൪ʹͳ͖ͬͯͨ௨৴ϥΠ ϒϥϦ Guzzle ʹɺϞοΫΛ attach Ͱ͖Δ ػೳ͕͋Γɺ͜ΕΛར༻͢ΔࣄͰɺ
Guzzleɹ Λར༻ͯ͠ωοτϫʔΫΞΫηεΛߦ͍ͬͯ Δίʔυɺ؆୯ʹςετΛॻ͘ࣄ͕Ͱ͖Δ Α͏ʹͳΔɻ
DBΞΫηε Λ ϞοΫͰ༻͢Δ
SimpleDBIͷ߹ https://github.com/ttsuruoka/php-simple-dbi
public static function get($member_id) { $con = SimpleDBI::conn(); $sql =
"SELECT * FROM member WHERE id = ?"; $row = $con->row($sql, array($member_id)); if ($row === false) { throw new AppException(); } return new self($row); }
public function testGet() { $row = ['id' => 1,'name' =>
'john']; " $mock = $this->getMock('DB', ['row'], [], '', false); $mock->expects($this->any()) ->method('row') ->will($this->returnValue($row)); " $class = new ReflectionClass(‘DB'); $property = $class->getProperty(‘instances'); $property->setAccessible(true); $property->setValue([null => $mock]); " $member = Member::getObject(1); $this->assertTrue($member instanceof Member); }
SimpleDBI::instance • SimpleDBIγϯάϧτϯΫϥεͳͷͰɺࣗࣗ Λϝϯόʹ͍࣋ͬͯΔ • ͜ͷϝϯόΛϞοΫʹࠩ͠ସ͑ͯ͠·͏ࣄͰɺҙ ͷڍಈΛ࣮ݱ͢Δ • DBͷ߹ fixture
͏ͷ͋Γ͚ͩͲίετͰ͔͍ ͷͰ෦ͷϩδοΫ͚ͩΛݕূ͍ͨ͠ͳΒϞοΫ ͏
·ͱΊ • IneternetΞΫηεDBΞΫηεϞοΫ͏ ͱ؆୯ʹ༻Ͱ͖ͯςετ͕ॻ͖͘͢ͳΔ Α • ͍ͬͯ͏͔ͳΜͰஔ͖͑Ͱ͖Δ͔Βຊ࣭ తͳ෦Ҏ֎ΨϯΨϯஔ͖͍͍͑ͯͱࢥ ͏Α
͋ͳ͕ͨॻ͍ͯΔ ͋ͷίʔυͰ ͪΐͬͱςετॻ͚ͦ͏ͳ ؾ͕͖ͯ͠·ͤΜ͔ʁ
େࣄͳࣄ manual ʹ શ෦ॻ͍ͯ͋Δ " https://phpunit.de/manual/current/ja/test- doubles.html#test-doubles.mock-objects
࣭ٙԠ(͋Ε)