Fake-a-web

Posted by fwoeck
on Saturday, June 13

Das fakeweb gem …

gem install fakeweb

... ist quasi für’s Web, was Mocks und Stubs für die Modelle – in Spec-Läufen kann man fakewebs für einzelne URLs definieren. Bei Net::HTTP-Aufrufen wird dann anstelle der richtigen Netzverbindung der vorher definierte lokale Inhalt ausgegeben.

Ich benutze Factory-Girl als Fixtureersatz und habe die Webdefinitionen fauler Weise mit in deren Datei spec/factories.rb gegeben, weil ich das irgendwie passend fand:

1
2
3
4
5
6
7
8
9
10
11
12
page1 = open("./spec/www_google_de.txt") {|f| f.read }
page2 = open("./spec/www_google_de_en.txt") {|f| f.read }

FakeWeb.register_uri(:get, "http://www.google.de", 
                      [{:string => page1, :status => ["200", "OK"], :times => 4},
                       {:string => page2, :status => ["200", "OK"], :times => 1},
                       {:string => page1, :status => ["200", "OK"], :times => 1}])

FakeWeb.register_uri(:get, "http://www.google.com", :string => 
                      "google.com here!", :status => ["200", "OK"])

FakeWeb.allow_net_connect = false

Hier werden zwei unterschiedliche Adressen definiert, die erste mit dem Inhalt zweier vorher durch

curl -is http://www.google.de/ > ./spec/www_google_de.txt
curl -is http://www.google.de/ncr > ./spec/www_google_de_en.txt

erzeugter Dateien. Indem man der Methode register_uri ein Parameterhash übergibt, kann man eine Rotation des Antwortverhaltens erreichen. Es würde also die ersten vier Male der Inhalt der page1 zurückgegeben, danach der von page2 etc. Nachdem das Array einmal “verbraucht” wurde, reagiert das System immer mit dem letzten Eintrag.

Will man auf eine Anfrage mit einem String antworten, so geht dies natürlich auch (siehe google.com).

Um sicherzugehen, dass während der Tests keine anderen Verbindungen geöffnet werden, kann man diese mit allow_net_connect = false blockieren. Der Verbindungsversuch an eine undefinierte Adresse wirft dann einen Fehler.

Der Model-Code, der schließlich die Netzanrufe auslöst, sieht beim mir so aus:


doc = Nokogiri::HTML(open(self.rwatch_url)).css(self.css_selector)

Das open ist einfach das aus open-uri. (Nokogiri ist übrigens ein hervorragender Ersatz für hpricot.)

Weblinks

github.com/chrisk/fakeweb