Ruby golpea con Faraday, no puedo hacerlo funcionar
Pregunta
Perdón por el título, estoy demasiado frustrado para pensar en algo mejor en este momento.
Tengo una clase, Judge
, que tiene un método #stats
.Este estadísticas Se supone que el método envía una solicitud GET a una API y obtiene algunos datos como respuesta.Estoy intentando probar esto y eliminar el método de estadísticas para no realizar una solicitud real.Así es como se ve mi prueba:
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
Esta es la clase que estoy probando:
class Judge
def self.stats
Faraday.get "some-domain-dot-com/stats"
end
end
Esto actualmente me da el error: Faraday does not implement: get
Entonces, ¿cómo se corta esto con Faraday?He visto métodos como:
stubs = Faraday::Adapter::Test::Stubs.new do |stub|
stub.get('http://stats-api.com') { [200, {}, 'Lorem ipsum'] }
end
Pero parece que no puedo aplicarlo de la manera correcta.¿Que me estoy perdiendo aqui?
Solución
Nota que Faraday.new devuelve una instancia de Faraday :: Conexión, no Faraday.Para que pueda intentar usar
allow_any_instance_of(Faraday::Connection).to receive(:get).and_return("some data")
Tenga en cuenta que no sé si devolviendo "algunos datos", como se muestra en su pregunta, ya que Faraday :: Connection.get debe devolver un objeto de respuesta, que incluiría el código y el código de estado en lugar de una cadena.Podrías probar algo como esto:
allow_any_instance_of(Faraday::Connection).to receive(:get).and_return(
double("response", status: 200, body: "some data")
)
Aquí hay una consola de Rails que muestra la clase que vuelve de 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
Otros consejos
Faraday la clase no tiene get
método, sólo la instancia lo hace.Como estás usando esto en un método de clase, lo que puedes hacer es algo como esto:
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
Luego, en tu prueba puedes configurar un doble:
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
Me encontré con el mismo problema con el error de Faraday::Adapter::Test::Stubs
con Faraday does not implement: get
.Parece que necesitas establecer stubs
a un adaptador de Faraday, como 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