Will man in Rails seine Modelle mittels Unit-Tests verifizieren, bieten die von Rails automatisch generierten Gerüste eine solide Grundlage. Allerdings stoßen diese Vorlagen an ihre Grenzen, sobald der Modellname von dem seiner zugehörigen Tabelle abweicht. Betrachten wir also folgendes Beispiel, in welchem sich der Klassenname und der Tabellenname voneinander unterscheiden.
class TestMe < ActiveRecord::Base
self.table_name = 'my_special_table'
#<class-definition here>
end
Beim Erzeugen eines neuen Railsprojektes werden automatisch Testklassen und zu jeder Klasse gehörende Fixtures angelegt. Dabei bekommt jede Fixture-Datei den Namen der zu testenden Klasse in pluralisierter Form. Im Beispielfall wäre das also TestMes.yml
. Führt man den Test nun aus, bekommt man prompt die Fehlermeldung Could not find table 'TestMes'
zurück. Interessanterweise lässt sich die Anwendung jedoch im Development- als auch im Production-Umgebung starten.
Was ist passiert?
Bei der Ausführung des Tests greift Rails auf die Testdaten — welche in den Fixtures definiert wurden — zurück. Dabei nutzt Rails wie gewohnt die in der database.yml
spezifizierte Datenbank. In Vorbereitung auf den Test werden die Daten aus den Fixtures in die entsprechende Datenbank gespeichert. Unglücklicherweise nutzt Rails ausschließlich den Dateinamen der Fixtures, um den entsprechenden Tabellennamen zu spezifizieren und ignoriert an dieser Stelle einfach den Befehl self.table_name = 'my_special_table'
aus der Klassendefinition. Da aber keine Tabelle mit dem entsprechenden Namen existiert, schlägt der Zugriff auf die Tabelle und in Folge dessen der Test fehl.
Lösung
Die Lösung für das Problem liegt auf der Hand, da wir die Ursache lokalisieren konnten. Die Fixture-Datei muss lediglich den Namen der entsprechenden Tabelle bekommen, anstatt den der zu testenden Klasse. In unserem Beispielfall also my_special_table.yml
und der Test funktioniert.
Achtung
Leider birgt diese Variante eine potentielle Fehlerquelle. Sollte sich der Tabellenname im Zuge der Entwicklung verändern, muss diese Änderung sowohl in der Klassendefinition vorgenommen werden als auch die Fixture-Datei den neuen Namen erhalten, um die Tests weiterhin lauffähig zu halten.