2014-06-20 7 views
7

Ich versuche, einen Komponententest zu schreiben, der überprüft, ob eine KeyError erstellt wird, wenn ein ungültiger Schlüssel an ein Wörterbuch übergeben wird.Testen für KeyError

Der Code, der die Ausnahme auslöst:

connections = SettingsManager().get_connections() 
try: 
    connection = connections[self.conn_name] 
except Exception: 
    self.log.error("Connection %s does not exist, exiting." % conn_name) 
    self.log.error(sys.exc_info()[0]) 
    raise 

Ich habe gesucht und gefunden KeyError Tests Lambda, aber ich habe nicht viel Glück gehabt. Hier ist der Test, den ich bisher habe, aber es ist fehlerhaft mit dem tatsächlichen KeyError.

def test_bad_connection(self): 
    #Testing to see if a non existant connection will fail gracefully. 
    records = [1, 2] 
    given_result = DataConnector("BadConnection").generate_data(self.table, records) 
    expected_result = "BadConnection" 

    self.assertRaises(KeyError, given_result[:1]) 

Antwort

9

assertRaises() wird Aufruf der Funktion für Sie, und behaupten, dass dieser Aufruf die Ausnahme auslöst:

records = [1, 2] 
connector = DataConnector("BadConnection") 

self.assertRaises(KeyError, connector.generate_data, self.table, records) 

, Alternativ assertRaises() als Kontext-Manager verwenden:

with self.assertRaises(KeyError) as raises: 
    DataConnector("BadConnection").generate_data(self.table, records) 

die hat den zusätzlichen Vorteil, dass Sie mit dem Kontextmanager auf die ausgelöste Ausnahme zugreifen können:

self.assertEqual(raises.exception.message, "BadConnection") 
+0

Danke - das erklärt es perfekt! Aus irgendeinem Grund konnte ich die 'raises.exception.msg' nicht verwenden, stattdessen verwendete ich 'raises.exception [0]' und das gab mir das erwartete Ergebnis. – OpenDataAlex

+1

@OpenDataAlex: Entschuldigung; Der Wert für 'exception.args [0]' wird auch als 'exception.message' angezeigt. Ich habe es einfach falsch geschrieben. –

+0

Coole Bohnen - funktionierte wie ein Charme :) – OpenDataAlex

3

self.assertRaise() dauert nur aufrufbar, so dass während

self.assertRaises(KeyError, given_result[:1])
würde Ihnen eine tatsächliche KeyError während des Tests,

self.assertRaises(KeyError, lambda: given_result[:1])
sollte funktionieren.

Allgemein gilt:
funktioniert nicht: self.assertRaises(KeyError, mydict[mykey]) #KeyError in Tests
funktioniert: self.assertRaises(KeyError, lambda: mydict[mykey])
funktioniert: self.assertRaises(KeyError, mydict.__getitem__, mykey) #but ist eine tatsächliche dict erfordert, anstelle einer Funktion