partial_mocks_documentation.html.svn-base

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

SVN-BASE
461
字号
<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><title>Documentation SimpleTest : les objets fantaisie partiels</title><link rel="stylesheet" type="text/css" href="docs.css" title="Styles"></head><body><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><h1>Documentation sur les objets fantaisie partiels</h1>        This page...        <ul><li>            <a href="#injection">Le probl猫me de l'injection d'un objet fantaisie</a>.        </li><li>            D茅placer la cr茅ation vers une m茅thode <a href="#creation">fabrique prot茅g茅e</a>.        </li><li>            <a href="#partiel">L'objet fantaisie partiel</a> g茅n猫re une sous-classe.        </li><li>            Les objets fantaisie partiels <a href="#moins">testent moins qu'une classe</a>.        </li></ul><div class="content">                    <p>                Un objet fantaisie partiel n'est ni plus ni moins                qu'un mod猫le de conception pour soulager un probl猫me sp茅cifique                du test avec des objets fantaisie, celui de placer                des objets fantaisie dans des coins serr茅s.                Il s'agit d'un outil assez limit茅 et peut-锚tre m锚me                une id茅e pas si bonne que 莽a. Elle est incluse dans SimpleTest                pour la simple raison que je l'ai trouv茅e utile                脿 plus d'une occasion et qu'elle m'a 茅pargn茅e                pas mal de travail dans ces moments-l脿.            </p>                <p><a class="target" name="injection"><h2>Le probl猫me de l'injection dans un objet fantaisie</h2></a></p>            <p>                Quand un objet en utilise un autre il est tr猫s simple                d'y faire circuler une version fantaisie d茅j脿 pr锚te                avec ses attentes. Les choses deviennent un peu plus d茅licates                si un objet en cr茅e un autre et que le cr茅ateur est celui                que l'on souhaite tester. Cela revient 脿 dire que l'objet                cr茅茅 devrait 锚tre une fantaisie, mais nous pouvons                difficilement dire 脿 notre classe sous test de cr茅er                un objet fantaisie plut么t qu'un "vrai" objet.                La classe test茅e ne sait m锚me pas qu'elle travaille dans un environnement de test.            </p>            <p>                Par exemple, supposons que nous sommes en train                de construire un client telnet et qu'il a besoin                de cr茅er une socket r茅seau pour envoyer ses messages.                La m茅thode de connexion pourrait ressemble 脿 quelque chose comme...<pre><strong>&lt;?phprequire_once('socket.php');class Telnet {    ...    function &amp;connect($ip, $port, $username, $password) {        $socket = &amp;new Socket($ip, $port);        $socket-&gt;read( ... );        ...    }}?&gt;</strong></pre>                Nous voudrions vraiment avoir une version fantaisie                de l'objet socket, que pouvons nous faire ?            </p>            <p>                La premi猫re solution est de passer la socket en                tant que param猫tre, ce qui force la cr茅ation                au niveau inf茅rieur. Charger le client de cette t芒che                est effectivement une bonne approche si c'est possible                et devrait conduire 脿 un remaniement -- de la cr茅ation                脿 partir de l'action. En fait, c'est l脿 une des mani猫res                avec lesquels tester en s'appuyant sur des objets fantaisie                vous force 脿 coder des solutions plus resserr茅es sur leur objectif.                Ils am茅liorent votre programmation.            </p>            <p>                Voici ce que 莽a devrait 锚tre...<pre>&lt;?phprequire_once('socket.php');class Telnet {    ...    <strong>function &amp;connect(&amp;$socket, $username, $password) {        $socket-&gt;read( ... );        ...    }</strong>}?&gt;</pre>                Sous-entendu, votre code de test est typique d'un cas                de test avec un objet fantaisie.<pre>class TelnetTest extends UnitTestCase {    ...    function testConnection() {<strong>        $socket = &amp;new MockSocket($this);        ...        $telnet = &amp;new Telnet();        $telnet-&gt;connect($socket, 'Me', 'Secret');        ...</strong>    }}</pre>                C'est assez 茅vident que vous ne pouvez descendre que d'un niveau.                Vous ne voudriez pas que votre application de haut niveau                cr茅e tous les fichiers de bas niveau, sockets et autres connexions                脿 la base de donn茅es dont elle aurait besoin.                Elle ne conna卯trait pas les param猫tres du constructeur de toute fa莽on.            </p>            <p>                La solution suivante est de passer l'objet cr茅茅 sous la forme                d'un param猫tre optionnel...<pre>&lt;?phprequire_once('socket.php');class Telnet {    ...<strong>    function &amp;connect($ip, $port, $username, $password, $socket = false) {        if (!$socket) {            $socket = &amp;new Socket($ip, $port);        }        $socket-&gt;read( ... );</strong>        ...        return $socket;    }}?&gt;</pre>                Pour une solution rapide, c'est g茅n茅ralement suffisant.                Ensuite le test est tr猫s similaire : comme si le param猫tre                茅tait transmis formellement...<pre>class TelnetTest extends UnitTestCase {    ...    function testConnection() {<strong>        $socket = &amp;new MockSocket($this);        ...        $telnet = &amp;new Telnet();        $telnet-&gt;connect('127.0.0.1', 21, 'Me', 'Secret', &amp;$socket);        ...</strong>    }}</pre>                Le probl猫me de cette approche tient dans son manque de nettet茅.                Il y a du code de test dans la classe principale et aussi                des param猫tres transmis dans le sc茅nario de test                qui ne sont jamais utilis茅s. Il s'agit l脿 d'une approche                rapide et sale, mais qui ne reste pas moins efficace                dans la plupart des situations.            </p>            <p>                Une autre solution encore est de laisser un objet fabrique                s'occuper de la cr茅ation...<pre>&lt;?phprequire_once('socket.php');class Telnet {<strong>    function Telnet(&amp;$network) {        $this-&gt;_network = &amp;$network;    }</strong>    ...    function &amp;connect($ip, $port, $username, $password) {<strong>        $socket = &amp;$this-&gt;_network-&gt;createSocket($ip, $port);        $socket-&gt;read( ... );</strong>        ...        return $socket;    }}?&gt;</pre>                Il s'agit l脿 probablement de la r茅ponse la plus travaill茅e                茅tant donn茅 que la cr茅ation est maintenant situ茅e                dans une petite classe sp茅cialis茅e. La fabrique r茅seau                peut 锚tre test茅e s茅par茅ment et utilis茅e en tant que fantaisie                quand nous testons la classe telnet...<pre>class TelnetTest extends UnitTestCase {    ...    function testConnection() {<strong>        $socket = &amp;new MockSocket($this);        ...        $network = &amp;new MockNetwork($this);        $network-&gt;setReturnReference('createSocket', $socket);        $telnet = &amp;new Telnet($network);        $telnet-&gt;connect('127.0.0.1', 21, 'Me', 'Secret');        ...</strong>    }}</pre>                Le probl猫me reste que nous ajoutons beaucoup de classes                脿 la biblioth猫que. Et aussi que nous utilisons beaucoup                de fabriques ce qui rend notre code un peu moins intuitif.                La solution la plus flexible, mais aussi la plus complexe.            </p>            <p>                Peut-on trouver un juste milieu ?

⌨️ 快捷键说明

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