2016-05-06 16 views
6

Capisco che se il codice go è strutturato in modo tale da essere programmato per le interfacce, è banale prendersi gioco; tuttavia, sto lavorando con un codice base che non posso cambiare (non è il mio) e non è questo il caso.patching scimmia Golang

Questo codice base è fortemente interconnesso e nulla è programmato su un'interfaccia, solo strutture, quindi nessuna iniezione di dipendenza.

Le strutture, di per sé, contengono solo altre strutture, quindi non posso neanche prendere in giro in quel modo. Non credo di poter fare nulla sui metodi, e le poche funzioni esistenti non sono variabili, quindi non c'è modo che io sappia scambiarle. L'ereditarietà non è una cosa in golang, quindi è un no go pure.

In linguaggi di scripting come python, possiamo modificare gli oggetti in fase di runtime, ovvero patch di scimmia. C'è qualcosa di paragonabile che posso fare a golang? Cercando di capire in qualche modo di testare/benchmark senza toccare il codice sottostante.

risposta

3

Quando mi sono imbattuto in questa situazione il mio approccio è di usare la mia interfaccia come un wrapper che permette di prendere in giro i test. Per esempio.

type MyInterface interface { 
    DoSomething(i int) error 
    DoSomethingElse() ([]int, error) 
} 

type Concrete struct { 
    client *somepackage.Client 
} 

func (c *Concrete) DoSomething(i int) error { 
    return c.client.DoSomething(i) 
} 

func (c *Concrete) DoSomethingElse() ([]int, error) { 
    return c.client.DoSomethingElse() 
} 

Ora si può prendere in giro il calcestruzzo nello stesso modo in cui si deridere somepackage.Client se anche si trattasse di un'interfaccia.

Come indicato nei commenti di seguito per @elithrar, è possibile incorporare il tipo che si desidera simulare in modo da essere solo costretti ad aggiungere metodi che richiedono il mocking. Ad esempio:

type Concrete struct { 
    *somepackage.Client 
} 

Al termine del genere, metodi aggiuntivi come DoSomethingNotNeedingMocking potrebbero essere chiamati direttamente sul Concrete senza dover aggiungere all'interfaccia/deridere fuori.

+0

Voglio assicurarmi che sto capendo correttamente questo. Stai suggerendo di definire una struttura che tenga conto di qualsiasi struttura con cui ho a che fare. Definire metodi su detta struct appena introdotta che chiamano i metodi della struct wrapped. Definisci un'interfaccia sulla struttura del wrapper, quindi prendi in giro in modo selettivo qualsiasi sottogruppo della logica sottostante che deve essere sbeffeggiata? Se la mia interpretazione è corretta, sembra che dovrei semplicemente riscrivere tutto il codice dato che è così intrecciato. Forse c'è da aspettarsi - immagino che non ci possa essere un'alternativa. –

+0

Questo, per quanto sfortunato, è esattamente ciò che sto suggerendo. – sberry

+1

Non è necessario chiamare/simulare i metodi che non è necessario sovrascrivere. Immetti il ​​tipo originale all'interno del tuo tipo, che promuove i metodi, quindi escludi solo i metodi che desideri: https://play.golang.org/p/oHW1JX8iFb – elithrar

Problemi correlati