2012-02-03 18 views
7

Al momento ho una classe Socket, che è fondamentalmente solo una classe wrapper OO per socket_* funzioni di PHP:Come posso testare il codice socket con PHPUnit?

class Socket { 
    public function __construct(...) { 
     $this->_resource = socket_create(...); 
    } 

    public function send($data) { 
     socket_send($this->_resource, $data, ...); 
    } 

    ... 
} 

Io non penso di poter prendere in giro la risorsa presa dal momento che sto utilizzando le funzioni di socket di PHP, in modo da in questo momento sono bloccato su come testare in modo affidabile questa classe.

+0

Per quanto posso vedere le parti omesse '' ... sono importanti – KingCrunch

+0

@KingCrunch: Si sono importanti in quanto sono ciò che voglio testare, ma non importanti per la mia domanda. Poiché le funzioni 'socket_ *' dipendono dalle risorse socket (che AFAIK non può essere deriso), non posso testare in modo affidabile questi metodi. – FtDRbwLXw6

+0

Ho alcune opinioni sul codice di rete testing unit in generale, ma non ho esperienza con PHP. Se non ricevi risposte in pochi giorni dagli sviluppatori PHP, scriverò alcuni commenti. Sarebbe utile se hai postato del codice che utilizza la tua classe socket, dato che probabilmente verrà preso in considerazione nella mia risposta. – selbie

risposta

16

Sembra che manchi un piccolo tassello alla filosofia del test dell'unità.

Il tuo problema è facilmente risolvibile creando un oggetto Stub. Stranamente, ho dato questa risposta più e più volte, quindi deve essere ampiamente ignorata da molte persone.

Perché vedo tanto confusione per quanto riguarda le differenze tra stub e prende in giro, mi permetta di stenderlo qui, così ...

  • un mock è una classe che estende un'altra classe che il test è direttamente dipendente, al fine di modificare i comportamenti di tale classe per semplificare il test.
  • Uno stub è una classe che implementa un API o interfaccia * che un test non può verificare facilmente sulla propria, al fine di rendere test possibile.

^- Questa è la descrizione più chiara dei due che abbia mai letto; Dovrei metterlo sul mio sito.

I socket dispongono di questa funzionalità utile in cui è possibile eseguire il binding sulla porta 0 a scopo di test (seriamente, si chiama "porta effimera").

Quindi provare questo:

class ListeningServerStub 
{ 
    protected $client; 

    public function listen() 
    { 
     $sock = socket_create(AF_INET, SOCK_STREAM, 0); 

     // Bind the socket to an address/port 
     socket_bind($sock, 'localhost', 0) or throw new RuntimeException('Could not bind to address'); 

     // Start listening for connections 
     socket_listen($sock); 

     // Accept incoming requests and handle them as child processes. 
     $this->client = socket_accept($sock); 
    } 

    public function read() 
    { 
     // Read the input from the client – 1024 bytes 
     $input = socket_read($client, 1024); 
     return $input; 
    } 
} 

creare questo oggetto e impostarlo di ascoltare del tuo test setUp() e smettere di ascoltare e distruggere nel tearDown(). Quindi, durante il test, connettersi al proprio server falso, recuperare i dati tramite la funzione read() e verificarlo.

Se questo ti aiuta molto, in considerazione darmi una taglia per pensare fuori dagli schemi tradizionali ;-)

+0

Non penso che tu abbia capito la mia domanda. Forse è colpa mia per non essere chiaro (se sì, fammi sapere come posso modificarlo per essere migliore). Il codice che voglio testare è *** il server, quindi lo stub il server non mi aiuterebbe. Né stubing il client, perché come ho sottolineato, anche lo stub dipenderebbe da una risorsa esterna (molto simile al test del codice del filesystem). – FtDRbwLXw6

+0

Immagino di renderlo più chiaro: cosa succede se cancello il client, ma un firewall sta bloccando il traffico sulla porta scelta. O alcune impostazioni di PHP non consentono l'apertura del socket. O scegliamo una porta <1024 su un sistema senza root. Ci sono un sacco di cose che potrebbero potenzialmente causare il fallimento dei test quando il codice non è in errore, e questo è un test inaffidabile. – FtDRbwLXw6

+0

@drrcknlsn Se vuoi che l'unità di aiuto test un server che non fa parte della tua classe Socket, allora sei ** orribilmente confuso ** per quanto riguarda il Test unitario. Se vuoi testare un server, passa semplicemente allo stub di un client (ovviamente!). Se nessuno dei precedenti, non solo era la domanda cattiva, ma sono totalmente confuso, ugh. –

Problemi correlati