Ruby se bat avec Faraday, je n'arrive pas à le faire fonctionner
Question
Désolé pour le titre, je suis trop frustré pour trouver quelque chose de mieux pour le moment.
J'ai un cours, Judge
, qui a une méthode #stats
.Ce Statistiques La méthode est censée envoyer une requête GET à une API et obtenir des données en réponse.J'essaie de tester cela et de supprimer la méthode stats afin de ne pas effectuer de requête réelle.Voici à quoi ressemble mon 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
Voici la classe que je teste :
class Judge
def self.stats
Faraday.get "some-domain-dot-com/stats"
end
end
Cela me donne actuellement l'erreur : Faraday does not implement: get
Alors, comment pouvez-vous remplacer ça par Faraday ?J'ai vu des méthodes comme :
stubs = Faraday::Adapter::Test::Stubs.new do |stub|
stub.get('http://stats-api.com') { [200, {}, 'Lorem ipsum'] }
end
Mais je n'arrive pas à l'appliquer correctement.Qu'est-ce que j'oublie ici?
La solution
Notez que Faraday.new renvoie une instance de Faraday::Connection, pas Faraday.Vous pouvez donc essayer d'utiliser
allow_any_instance_of(Faraday::Connection).to receive(:get).and_return("some data")
Notez que je ne sais pas si le renvoi de "certaines données" comme indiqué dans votre question est correct, car Faraday::Connection.get devrait renvoyer un objet de réponse, qui inclurait le corps et le code d'état au lieu d'une chaîne.Vous pourriez essayer quelque chose comme ceci :
allow_any_instance_of(Faraday::Connection).to receive(:get).and_return(
double("response", status: 200, body: "some data")
)
Voici une console Rails qui montre la classe que vous récupérez 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
Autres conseils
Faraday, la classe n'a pas get
méthode, seule l’instance le fait.Puisque vous utilisez ceci dans une méthode de classe, ce que vous pouvez faire ressemble à ceci :
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
Ensuite, dans votre test, vous pouvez simplement configurer un double :
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
J'ai rencontré le même problème avec Faraday::Adapter::Test::Stubs
se tromper avec Faraday does not implement: get
.Il semble que vous deviez définir stubs
à un adaptateur Faraday, comme ceci :
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