Lotting rubino con Faraday, non riesco a farlo funzionare
Domanda
Scusa per il titolo, sono troppo frustrato per trovare qualcosa di meglio in questo momento.
Ho una classe, Judge
, che ha un metodo #stats
.Questo metodo statistiche dovrebbe inviare una richiesta di ricezione a un'API e ottenere alcuni dati come risposta.Sto cercando di testare questo e stub il metodo delle statistiche in modo da non eseguire una richiesta effettiva.Questo è ciò che ha il mio test:
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
.
Questa è la classe che sto testando:
class Judge
def self.stats
Faraday.get "some-domain-dot-com/stats"
end
end
.
Questo attualmente mi dà l'errore: Faraday does not implement: get
Allora, come lo stai macchiando con Faraday?Ho visto metodi come:
stubs = Faraday::Adapter::Test::Stubs.new do |stub|
stub.get('http://stats-api.com') { [200, {}, 'Lorem ipsum'] }
end
.
Ma non riesco a applicarlo nel modo giusto.Cosa mi manca qui?
Soluzione
Nota che FARADAY.New restituisce un'istanza di Faraday :: Connessione, non Faraday.Quindi puoi provare a usare
allow_any_instance_of(Faraday::Connection).to receive(:get).and_return("some data")
.
Nota che non so se restituire "alcuni dati" come mostrato nella tua domanda è corretto, poiché FARADAY :: Connection.get deve restituire un oggetto di risposta, che includerebbe il corpo e il codice di stato invece di una stringa.Potresti provare qualcosa del genere:
allow_any_instance_of(Faraday::Connection).to receive(:get).and_return(
double("response", status: 200, body: "some data")
)
.
Ecco una console di rotaie che mostra la classe che torni da Faraday.New
$ 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
. Altri suggerimenti
FARADAY La classe non ha metodo get
, solo l'istanza lo fa.Dato che stai usando questo in un metodo di classe ciò che puoi fare è qualcosa del genere:
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
.
Poi nel tuo test puoi semplicemente impostare un doppio:
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
. Ho corso nello stesso problema con Faraday::Adapter::Test::Stubs
Erroring con Faraday does not implement: get
.Sembra che sia necessario impostare stubs
in un adattatore di faraday, come:
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
.