2015-05-20 11 views
9

mock (http://mock.readthedocs.org/en/latest/index.html) è un ottimo strumento in python per il test dell'unità. Può facilmente prendere in giro un metodo o una classe o un dotto. Ma ho riscontrato un problema che non riuscivo a trovare un modo semplice per affrontare con finta.Come consentire a MagicMock di comportarsi come un dittato?

Questa è la funzione da testare:

def function_to_be_tested(id, responses): 
    if not id in responses: 
     print '%s not exist'%pole_id 
     return 

    if id in responses.redundantErrorResponses: 
     print '%s is redundant'%pole_id 
     return 

    do_something() 

argomento risposte è un dict come oggetto che ha alcuni altri attributi (come redundantErrorResponses) eccetto dict caratteristiche intrinseche. Ora voglio costruire una risposta falsa per lasciare che id in responses sia True e id in responses.redundantErrorResponses sia False. Questo è quello che faccio: Si è verificato

pole_id = 30 
pole_value = 100 
pole_dic = {pole_id:pole_value} 
mock_responses = MagicMock() 
mock_responses.__getitem__.side_effect = lambda k: pole_dic[k] 
mock_responses.__iter__.side_effect = iter(pole_dic) 
mock_responses.redundantErrorResponses = {} 

Ma di errore:

function_to_be_tested(pole_id, mock_responses) 

>>30 not exist 

Così come posso costruire un oggetto MagicMock nel frattempo può iterare come un dict o come posso costruire un dict frattempo supporta le funzioni di MagicMock (aggiungere attributo liberamente)?

+0

dovrebbe essere '' 'function_to_be_tested (pole_id, mock_responses)' ''? – wwii

risposta

11

Perché scherzare con __iter__? Mi sembra che si desidera pasticciare con __contains__:

>>> import mock 
>>> m = mock.MagicMock() 
>>> d = {'foo': 'bar'} 
>>> m.__getitem__.side_effect = d.__getitem__ 
>>> m.__iter__.side_effect = d.__iter__ 
>>> m['foo'] 
'bar' 
>>> 'foo' in m 
False 
>>> m.__contains__.side_effect = d.__contains__ 
>>> 'foo' in m 
True 
1

È sempre possibile creare una classe stupida per fare la stessa cosa.

In [94]: class MockResponses(dict): 
    ....:  @property 
    ....:  def redundantErrorResponses(self): 
    ....:   return {} 
+0

Ero molto vicino a raccomandare la stessa cosa :-). Una nota: non hai nemmeno bisogno di una 'proprietà' qui - Potresti avere' redundantErrorResponses' come un attributo di classe dato che stai solo creando 1 istanza in ogni caso ... – mgilson

+0

Sì, questa è la mia soluzione iniziale , ma voglio solo sapere "come costruire un oggetto MagicMock nel frattempo può iterare come un dittico". La risposta di @ mgilson è corretta. – lengxuehx

Problemi correlati