2015-04-10 12 views
10

Come posso chiamare condizionatamente il metodo dell'originale in una simulazione?Mocking condizionale: chiamare la funzione originale se la condizione corrisponde a

In questo esempio, desidero solo falsificare un valore restituito se bar=='x'. Altrimenti voglio chiamare il metodo originale.

def mocked_some_method(bar): 
    if bar=='x': 
     return 'fake' 
    return some_how_call_original_method(bar) 

with mock.patch('mylib.foo.some_method', mocked_some_method): 
    do_some_stuff() 

So che è un po 'strano. Se voglio simulare do_some_stuff() nel lato , dovrebbe essere senza condizione. Tutte le chiamate (non alcune) a some_method devono essere prese in giro.

Nel mio caso si tratta di un test di integrazione, non di un s minuscolo all-in-one e mylib.foo.some_method è una sorta di dispatcher che viene utilizzato molto spesso. E in un caso ho bisogno di falsificare il risultato.

risposta

12

Se è necessario sostituire semplicemente il comportamento senza attenzione alle chiamate assurde, è possibile utilizzare l'argomento new; altrimenti puoi usare side_effect che accetta un callable.

Immagino che some_method sia un metodo oggetto (anziché staticmethod) quindi è necessario un riferimento al relativo oggetto per chiamarlo. Il tuo wrapper deve dichiarare come primo argomento che l'oggetto e la tua patch usano autospec=True per utilizzare la firma corretta per il caso side_effect.

Il trucco finale è salvare il riferimento al metodo originale e utilizzarlo per effettuare la chiamata.

orig = mylib.foo.some_method 
def mocked_some_method(self, bar): 
    if bar=='x': 
     return 'fake' 
    return orig(self, bar) 

#Just replace: 
with mock.patch('mylib.foo.some_method', new=mocked_some_method): 
    do_some_stuff() 

#Replace by mock 
with mock.patch('mylib.foo.some_method', side_effect=mocked_some_method, autospec=True) as mock_some_method: 
    do_some_stuff() 
    assert mock_some_method.called 
+0

Cosa intendi con "statico" qui: "Immagino che some_method non sia statico ..."? – guettli

+0

Hai ragione. fingere come wrapper non è la migliore pratica. Ho aggiornato la domanda per riflettere questo. – guettli

+0

@guettli Dalla tua domanda posso solo supporre che 'some_method' non sia' @ staticmethod' ma un metodo a oggetti .... Cambierò la mia risposta rimuovendo la nota a margine, ma dovrebbe già soddisfare i tuoi requisiti. –

Problemi correlati