2014-12-02 6 views
12

Ho due moduli diversi nel mio progetto. Uno è un file di configurazione che contieneCome applicare una costante a Python

LOGGING_ACTIVATED = False 

Questa costante viene utilizzata nel secondo modulo (consente di chiamare principale) come la seguente:

if LOGGING_ACTIVATED: 
    amqp_connector = Connector() 

Nella mia classe di test per il modulo principale che vorrei di patch questa costante con il valore

True 

Purtroppo la seguente non funziona

@patch("config.LOGGING_ACTIVATED", True) 

né questo lavoro:

@patch.object("config.LOGGING_ACTIVATED", True) 

Qualcuno sa come patch una costante da diversi moduli?

risposta

20

Se il test if LOGGING_ACTIVATED: si verifica al livello del modulo, è necessario assicurarsi che tale modulo non sia stato ancora importato per primo. Il codice a livello di modulo viene eseguito una volta sola (la prima volta che il modulo viene importato ovunque), non è possibile testare il codice che non verrà eseguito di nuovo.

Se il test è in una funzione, si noti che il nome globale utilizzato è LOGGING_ACTIVATED, non config.LOGGING_ACTIVATED. Come tale è necessario applicare una patch fuori main.LOGGING_ACTIVATED qui:

@patch("main.LOGGING_ACTIVATED", True) 

quanto questo è il riferimento effettivo si voleva sostituire.

Vedere anche Where to patch section della documentazione mock.

È consigliabile considerare il refactoring del codice a livello di modulo in qualcosa di più verificabile. Sebbene sia possibile forzare un ricaricamento del codice del modulo eliminando l'oggetto modulo dalla mappatura sys.modules, è chiaro che è necessario spostare il codice che si desidera testabile in una funzione.

Così, se il codice di ora sembra qualcosa di simile:

if LOGGING_ACTIVATED: 
    amqp_connector = Connector() 

è consigliabile utilizzare una funzione invece:

def main(): 
    global amqp_connector 
    if LOGGING_ACTIVATED: 
     amqp_connector = Connector() 

main() 

o produrre un oggetto con attributi anche.

+0

Mi ha colpito, ero impegnato a cercare di capire se 'patch()' è in grado di applicare patch al modulo '__main__', nel caso in cui ciò fosse significato da" call it main ". –

+0

@SteveJessop: per la cronaca: si lo è. '__main__' è solo un altro modulo per quanto riguarda Python, quindi' patch ('__ main __. somename', somevalue) 'funziona. –

+0

grazie per la risposta veloce. L'istruzione if è effettivamente a livello di modulo. E nella mia classe di test importa il modulo. Quindi non c'è possibilità di riscriverlo per i metodi di prova singoli? –