partial_mocks_documentation.html.svn-base

来自「PHP 知识管理系统(基于树结构的知识管理系统), 英文原版的PHP源码。」· SVN-BASE 代码 · 共 461 行 · 第 1/2 页

SVN-BASE
461
字号
            </p>                <p><a class="target" name="creation"><h2>M茅thode fabrique prot茅g茅e</h2></a></p>            <p>                Il existe une technique pour palier 脿 ce probl猫me                sans cr茅er de nouvelle classe dans l'application;                par contre elle induit la cr茅ation d'une sous-classe au moment du test.                Premi猫rement nous d茅pla莽ons la cr茅ation de la socket dans sa propre m茅thode...<pre>&lt;?phprequire_once('socket.php');class Telnet {    ...    function &amp;connect($ip, $port, $username, $password) {<strong>        $socket = &amp;$this-&gt;_createSocket($ip, $port);</strong>        $socket-&gt;read( ... );        ...    }<strong>        function &amp;_createSocket($ip, $port) {        return new Socket($ip, $port);    }</strong>}?&gt;</pre>                Il s'agit l脿 de la seule modification dans le code de l'application.            </p>            <p>                Pour le sc茅nario de test, nous devons cr茅er                une sous-classe de mani猫re 脿 intercepter la cr茅ation de la socket...<pre><strong>class TelnetTestVersion extends Telnet {    var $_mock;        function TelnetTestVersion(&amp;$mock) {        $this-&gt;_mock = &amp;$mock;        $this-&gt;Telnet();    }        function &amp;_createSocket() {        return $this-&gt;_mock;    }}</strong></pre>                Ici j'ai d茅plac茅 la fantaisie dans le constructeur,                mais un setter aurait fonctionn茅 tout aussi bien.                Notez bien que la fantaisie est plac茅e dans une variable                d'objet avant que le constructeur ne soit attach茅.                C'est n茅cessaire dans le cas o霉 le constructeur appelle                 <span class="new_code">connect()</span>.                Autrement il pourrait donner un valeur nulle 脿 partir de                <span class="new_code">_createSocket()</span>.            </p>            <p>                Apr猫s la r茅alisation de tout ce travail suppl茅mentaire                le sc茅nario de test est assez simple.                Nous avons juste besoin de tester notre nouvelle classe 脿 la place...<pre>class TelnetTest extends UnitTestCase {    ...    function testConnection() {<strong>        $socket = &amp;new MockSocket($this);        ...        $telnet = &amp;new TelnetTestVersion($socket);        $telnet-&gt;connect('127.0.0.1', 21, 'Me', 'Secret');        ...</strong>    }}</pre>                Cette nouvelle classe est tr猫s simple bien s没r.                Elle ne fait qu'initier une valeur renvoy茅e, 脿 la mani猫re                d'une fantaisie. Ce serait pas mal non plus si elle pouvait                v茅rifier les param猫tres entrants.                Exactement comme un objet fantaisie.                Il se pourrait bien que nous ayons 脿 r茅aliser cette astuce r茅guli猫rement :                serait-il possible d'automatiser la cr茅ation de cette sous-classe ?            </p>                <p><a class="target" name="partiel"><h2>Un objet fantaisie partiel</h2></a></p>            <p>                Bien s没r la r茅ponse est "oui"                ou alors j'aurais arr锚t茅 d'茅crire depuis quelques temps d茅j脿 !                Le test pr茅c茅dent a repr茅sent茅 beaucoup de travail,                mais nous pouvons g茅n茅rer la sous-classe en utilisant                une approche 脿 celle des objets fantaisie.            </p>            <p>                Voici donc une version avec objet fantaisie partiel du test...<pre><strong>Mock::generatePartial(        'Telnet',        'TelnetTestVersion',        array('_createSocket'));</strong>class TelnetTest extends UnitTestCase {    ...    function testConnection() {<strong>        $socket = &amp;new MockSocket($this);        ...        $telnet = &amp;new TelnetTestVersion($this);        $telnet-&gt;setReturnReference('_createSocket', $socket);        $telnet-&gt;Telnet();        $telnet-&gt;connect('127.0.0.1', 21, 'Me', 'Secret');        ...</strong>    }}</pre>                La fantaisie partielle est une sous-classe de l'original                dont on aurait "remplac茅" les m茅thodes s茅lectionn茅es                avec des versions de test. L'appel 脿 <span class="new_code">generatePartial()</span>                n茅cessite trois param猫tres : la classe 脿 sous classer,                le nom de la nouvelle classe et une liste des m茅thodes 脿 simuler.            </p>            <p>                Instancier les objets qui en r茅sultent est plut么t d茅licat.                L'unique param猫tre du constructeur d'un objet fantaisie partiel                est la r茅f茅rence du testeur unitaire.                Comme avec les objets fantaisie classiques c'est n茅cessaire                pour l'envoi des r茅sultats de test en r茅ponse 脿 la v茅rification des attentes.            </p>            <p>                Une nouvelle fois le constructeur original n'est pas lanc茅.                Indispensable dans le cas o霉 le constructeur aurait besoin                des m茅thodes fantaisie : elles n'ont pas encore 茅t茅 initi茅es !                Nous initions les valeurs retourn茅es 脿 cet instant et                ensuite lan莽ons le constructeur avec ses param猫tres normaux.                Cette construction en trois 茅tapes de "new",                suivie par la mise en place des m茅thodes et ensuite                par la lancement du constructeur proprement dit est                ce qui distingue le code d'un objet fantaisie partiel.            </p>            <p>                A part pour leur construction, toutes ces m茅thodes                fantaisie ont les m锚mes fonctionnalit茅s que dans                le cas des objets fantaisie et toutes les m茅thodes                non fantaisie se comportent comme avant.                Nous pouvons mettre en place des attentes tr猫s facilement...<pre>class TelnetTest extends UnitTestCase {    ...    function testConnection() {        $socket = &amp;new MockSocket($this);        ...        $telnet = &amp;new TelnetTestVersion($this);        $telnet-&gt;setReturnReference('_createSocket', $socket);<strong>        $telnet-&gt;expectOnce('_createSocket', array('127.0.0.1', 21));</strong>        $telnet-&gt;Telnet();        $telnet-&gt;connect('127.0.0.1', 21, 'Me', 'Secret');        ...<strong>        $telnet-&gt;tally();</strong>    }}</pre>            </p>                <p><a class="target" name="moins"><h2>Tester moins qu'une classe</h2></a></p>            <p>                Les m茅thodes issues d'un objet fantaisie n'ont pas                besoin d'锚tre des m茅thodes fabrique, Il peut s'agir                de n'importe quelle sorte de m茅thode.                Ainsi les objets fantaisie partiels nous permettent                de prendre le contr么le de n'importe quelle partie d'une classe,                le constructeur except茅. Nous pourrions m锚me aller jusqu'脿                cr茅er des fantaisies sur toutes les m茅thodes 脿 part celle                que nous voulons effectivement tester.            </p>            <p>                Cette situation est assez hypoth茅tique, 茅tant donn茅                que je ne l'ai jamais essay茅e. Je suis ouvert 脿 cette possibilit茅,                mais je crains qu'en for莽ant la granularit茅 d'un objet                on n'obtienne pas forc茅ment un code de meilleur qualit茅.                Personnellement j'utilise les objets fantaisie partiels                comme moyen de passer outre la cr茅ation ou alors                de temps en temps pour tester le mod猫le de conception TemplateMethod.            </p>            <p>                Pour choisir le m茅canisme 脿 utiliser, on en revient                toujours aux standards de code de votre projet.            </p>            </div>        References and related information...        <ul><li>            La page du projet SimpleTest sur            <a href="http://sourceforge.net/projects/simpletest/">SourceForge</a>.        </li><li>            <a href="http://simpletest.org/api/">L'API compl猫te pour SimpleTest</a>            脿 partir de PHPDoc.        </li><li>            La m茅thode fabrique prot茅g茅e est d茅crite dans            <a href="http://www-106.ibm.com/developerworks/java/library/j-mocktest.html">            cet article d'IBM</a>. Il s'agit de l'unique papier            formel que j'ai vu sur ce probl猫me.        </li></ul><div class="menu_back"><div class="menu"><a href="index.html">SimpleTest</a>                |                <a href="overview.html">Overview</a>                |                <a href="unit_test_documentation.html">Unit tester</a>                |                <a href="group_test_documentation.html">Group tests</a>                |                <a href="mock_objects_documentation.html">Mock objects</a>                |                <a href="partial_mocks_documentation.html">Partial mocks</a>                |                <a href="reporter_documentation.html">Reporting</a>                |                <a href="expectation_documentation.html">Expectations</a>                |                <a href="web_tester_documentation.html">Web tester</a>                |                <a href="form_testing_documentation.html">Testing forms</a>                |                <a href="authentication_documentation.html">Authentication</a>                |                <a href="browser_documentation.html">Scriptable browser</a></div></div><div class="copyright">            Copyright<br>Marcus Baker 2006        </div></body></html>

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?