2010-09-28 13 views
15

Sto usando la libreria mock scritta da Michael Foord per aiutare con i miei test su un'applicazione django.Come simulare chiamate di funzioni concatenate in python?

Vorrei testare che sto configurando correttamente la mia query, ma non credo di dover effettivamente colpire il database, quindi sto cercando di prendere in giro la query.

Posso prendere in giro la prima parte della query, ma non otterrò i risultati desiderati quando aggiungo ulteriori elementi.

La funzione:

 
    @staticmethod 
    def get_policies(policy_holder, current_user): 
     if current_user.agency: 
      return Policy.objects.filter(policy_holder=policy_holder, version__agency=current_user.agency).distinct() 
     else: 
      return Policy.objects.filter(policy_holder=policy_holder) 

e la mia prova: La prima affermazione passa, il secondo fallisce.

 
    def should_get_policies_for_agent__user(self): 
     with mock.patch.object(policy_models.Policy, "objects") as query_mock: 
      user_mock = mock.Mock() 
      user_mock.agency = "1234" 
      policy_models.Policy.get_policies("policy_holder", user_mock) 
      self.assertEqual(query_mock.method_calls, [("filter",(), { 
       'policy_holder': "policy_holder", 
       'version__agency': user_mock.agency, 
      })]) 
      self.assertTrue(query_mock.distinct.called) 

Sono abbastanza sicuro che il problema è che il query_mock iniziale, sta tornando un nuovo finto dopo la .filter() viene chiamato, ma non so come catturare quel nuovo finto e assicurarsi .distinct() è stato chiamato su di esso.

C'è un modo migliore per testare quello che sto cercando di ottenere? Sto cercando di assicurarmi che venga chiamata la query corretta.

+4

Si prega di non perdere tempo a prendere in giro le query Django. Basta creare un "fixture" ed eseguire le query reali sui dati della fixture. È molto più semplice e produce risultati di test molto più utili. –

+0

Grazie per il tuo commento. Abbiamo usato le fixture ma stiamo cercando di allontanarci da loro in alcuni casi per due motivi. uno: i nostri modelli sono complessi con molte relazioni. la predisposizione di fixture per questo caso particolare richiederebbe dati di installazione per utenti, aziende, agenzie, assicurati, polizze e versioni. Non ho bisogno di eseguire effettivamente la query, ho solo bisogno di assicurarsi che sia impostato correttamente. due: i nostri test funzionano molto più lentamente usando gli apparecchi – Aaron

+0

@Aaron: Facciamo questo. (1) eseguire l'amministratore integrato per creare i dati. (2) fare un dumpdata delle pagine di amministrazione costruite a mano. I nostri proiettori sono piccoli (dozzine di file al massimo), caricano molto velocemente e ci salvano cercando di deridere Django stesso. –

risposta

15

Ogni oggetto fittizio rimane sull'oggetto fittizio restituito quando viene chiamato. Puoi ottenerlo usando la proprietà return_value dell'oggetto mock.

Per esempio,

self.assertTrue(query_mock.distinct.called) 

distinti non è stato chiamato sul finto, è stato chiamato sul valore restituito dal metodo del filtro del vostro finto, in modo da poter affermare che distinto è stato chiamato in questo modo :

+0

Così semplice ... Grazie per aver fornito una risposta utile e chiara. Molto più utile delle battute avanti e indietro tra te e S.Lott ... – Aaron

Problemi correlati