Ruby Stubbing mit Faraday, ich bekomme es nicht zum Laufen
Frage
Entschuldigung für den Titel, ich bin zu frustriert, um mir im Moment etwas Besseres einfallen zu lassen.
Ich habe ein klasse, Judge
, das eine Methode hat #stats
.Das Statistiken Die Methode soll eine GET-Anfrage an eine API senden und einige Daten als Antwort erhalten.Ich versuche dies zu testen und die Statistikmethode zu blockieren, damit ich keine tatsächliche Anfrage ausführe.So sieht mein Test aus:
describe Judge do
describe '.stats' do
context 'when success' do
subject { Judge.stats }
it 'returns stats' do
allow(Faraday).to receive(:get).and_return('some data')
expect(subject.status).to eq 200
expect(subject).to be_success
end
end
end
end
Dies ist die Klasse, die ich teste:
class Judge
def self.stats
Faraday.get "some-domain-dot-com/stats"
end
end
Dies gibt mir derzeit den Fehler: Faraday does not implement: get
Wie löscht man das also mit Faraday?Ich habe Methoden gesehen wie:
stubs = Faraday::Adapter::Test::Stubs.new do |stub|
stub.get('http://stats-api.com') { [200, {}, 'Lorem ipsum'] }
end
Aber ich kann es anscheinend nicht richtig anwenden.Was fehlt mir hier?
Lösung
Beachten Sie, dass Faraday.new eine Instanz von Faraday::Connection und nicht Faraday zurückgibt.Sie können es also ausprobieren
allow_any_instance_of(Faraday::Connection).to receive(:get).and_return("some data")
Beachten Sie, dass ich nicht weiß, ob die Rückgabe „einiger Daten“, wie in Ihrer Frage gezeigt, korrekt ist, da Faraday::Connection.get ein Antwortobjekt zurückgeben sollte, das den Text und den Statuscode anstelle einer Zeichenfolge enthält.Sie könnten so etwas versuchen:
allow_any_instance_of(Faraday::Connection).to receive(:get).and_return(
double("response", status: 200, body: "some data")
)
Hier ist eine Rails-Konsole, die die Klasse anzeigt, die Sie von Faraday.new zurückerhalten
$ rails c
Loading development environment (Rails 4.1.5)
2.1.2 :001 > fara = Faraday.new
=> #<Faraday::Connection:0x0000010abcdd28 @parallel_manager=nil, @headers={"User-Agent"=>"Faraday v0.9.1"}, @params={}, @options=#<Faraday::RequestOptions (empty)>, @ssl=#<Faraday::SSLOptions (empty)>, @default_parallel_manager=nil, @builder=#<Faraday::RackBuilder:0x0000010abcd990 @handlers=[Faraday::Request::UrlEncoded, Faraday::Adapter::NetHttp]>, @url_prefix=#<URI::HTTP:0x0000010abcd378 URL:http:/>, @proxy=nil>
2.1.2 :002 > fara.class
=> Faraday::Connection
Andere Tipps
Faraday hat die Klasse nein get
Methode, nur die Instanz.Da Sie dies in einer Klassenmethode verwenden, können Sie etwa Folgendes tun:
class Judge
def self.stats
connection.get "some-domain-dot-com/stats"
end
def self.connection=(val)
@connection = val
end
def self.connection
@connection ||= Faraday.new(some stuff to build up connection)
end
end
Dann können Sie in Ihrem Test einfach ein Double einrichten:
let(:connection) { double :connection, get: nil }
before do
allow(connection).to receive(:get).with("some-domain-dot-com/stats").and_return('some data')
Judge.connection = connection
end
Ich hatte das gleiche Problem mit Faraday::Adapter::Test::Stubs
Fehler mit Faraday does not implement: get
.Es scheint, dass Sie eine Einstellung vornehmen müssen stubs
zu einem Faraday-Adapter, etwa so:
stubs = Faraday::Adapter::Test::Stubs.new do |stub|
stub.get("some-domain-dot-com/stats") { |env| [200, {}, 'egg'] }
end
test = Faraday.new do |builder|
builder.adapter :test, stubs
end
allow(Faraday).to receive(:new).and_return(test)
expect(Judge.stats.body).to eq "egg"
expect(Judge.stats.status).to eq 200