2014-09-15 14 views
18

Ho bisogno di creare una specie di MockMixin per i miei test. Dovrebbe includere i mock per tutto ciò che chiama fonti esterne. Ad esempio, ogni volta che salvi il modello nel pannello di amministrazione, chiamo alcuni URL remoti. Sarebbe bene, per avere quella deriso e utilizzare così:Test di Django - patch object in tutti i test

class ExampleTestCase(MockedTestCase): 
    # tests 

Così ogni volta li risparmio modello di amministrazione, ad esempio, nei test funzionali, questo finto viene applicata invece di chiamare URL remoti.

È effettivamente possibile? Sono in grado di farlo per 1 test particolare, non è un problema. Ma sarebbe più utile avere un pasticcio globale perché lo uso molto.

risposta

28

Secondo il mock documentation:

patch può essere utilizzato come un decoratore di classe TestCase. Funziona con decorando ogni metodo di test nella classe. Questo riduce il codice di piastra di riscaldamento quando i metodi di test condividono un set di patching comune.

Ciò significa che è possibile creare una classe di test di base con @patch decoratore applicata su di esso che deridere le chiamate esterne mentre ogni metodo di prova all'interno sarebbe stato giustiziato.

Inoltre, è possibile utilizzare start() and stop() metodi di patcher in setUp() e tearDown() metodi rispettivamente:

class BaseTestCase(TestCase): 
    def setUp(self): 
     self.patcher = patch('mymodule.foo') 
     self.mock_foo = self.patcher.start() 

    def tearDown(self): 
     self.patcher.stop() 
+2

E questo significa anche che devo decorare ciascuno dei miei casi di test, e non la classe di test '' 'Mixin'''. È anche piuttosto scomodo dover inserire parametri aggiuntivi per ogni metodo di prova. Ma è meglio di niente. – tunarob

+0

@galozek si prega di consultare gli argomenti rilevanti: [qui] (http://stackoverflow.com/questions/12219967/how-to-mock-a-base-class-with-python-mock-library) e [here] (http://stackoverflow.com/questions/11194847/how-do-i-directly-mock-a-superclass-with-python-mock). – alecxe

+0

@galozek Ho anche aggiunto un'altra opzione: controlla se è utile. Grazie. – alecxe

13

solo per aggiungere alla risposta di alecxe, se si utilizza teardown poi secondo la documentazione

voi deve assicurare che l'assegnazione delle patch sia "annullata" chiamando stop

Quindi, se viene sollevata un'eccezione nei test, le patch non verranno annullate. Un modo migliore sarebbe chiamare addCleanup all'interno del tuo setUp. Quindi è possibile omettere del tutto il metodo tearDown.

class BaseTestCase(TestCase): 
    def setUp(self): 
     self.patcher = patch('mymodule.foo') 
     self.mock_foo = self.patcher.start() 
     self.addCleanup(self.patcher.stop) # add this line 
+1

'tearDown' sarà sempre chiamato, anche se i test generano un'eccezione. – Dan

+2

Dalla documentazione: "Se setUp() fallisce, il che significa che tearDown() non viene chiamato, quindi verranno comunque chiamate tutte le funzioni di pulizia aggiunte." Quindi è ancora meglio chiamare 'addCleanup' piuttosto che sperare che non vengano sollevate eccezioni in' setUp'. – Meistro

Problemi correlati