2017-12-01 4 views
5

Ich verwende Rails 5 mit Rspec 3. Wie mache ich eine Klasse in meiner Rspec-Methode? Ich habe die folgende KlasseWie spotze ich eine Klasse mit Rspec und Rails?

require 'rails_helper' 

describe CryptoCurrencyService do 

    describe ".sell" do 

    it "basic_sell" do 
     last_buy_price = 3000 
     last_transaction = MoneyMakerTransaction.new({ 
     :transaction_type => "buy", 
     :amount_in_usd => "100", 
     :btc_price_in_usd => "#{last_buy_price}" 
     }) 
     @client = Coinbase::Wallet::Client.new(api_key: ENV['COINBASE_KEY'], api_secret: ENV['COINBASE_SECRET']) 
     sell_price = 4000 
     assert sell_price > last_buy_price * (1 + MoneyMakerThreshhold.find_buy.pct_change) 

     allow(@client).to receive(:sell_price).and_return({"base"=>"BTC", "currency"=>"USD", "amount"=>"#{sell_price}"}) 

     svc = CryptoCurrencyService.new 
     svc.sell(last_transaction) 
     last_transaction = MoneyMakerTransaction.find_latest_record 
     assert last_transaction.transaction_type, "sell" 
    end 

    end 

end 

Anstatt tatsächlich die Klasse instanziieren „Coinbase :: Wallet“ in der Linie

@client = Coinbase::Wallet::Client.new(api_key: ENV['COINBASE_KEY'], api_secret: ENV['COINBASE_SECRET']) 

Ich möchte Mock taht erstellen ich dann in meine Dienstklasse einfügen könnte , die ich gerade teste. Wie steht es jetzt, wenn ich die Dinge laufen, wird die tatsächliche zugrundeliegende Klasse instanziiert zu werden, um die Laufzeit Fehler führt ...

1) CryptoCurrencyService.sell basic_sell 
    Failure/Error: payment_method = client.payment_methods()[0] 

    Coinbase::Wallet::AuthenticationError: 
     invalid api key 
+1

verspotten Haben Sie da 'rspec-mocks'? https://github.com/rspec/rspec-mocks –

+1

Ja, aber ich sehe nichts, was meiner Situation entspricht. – Dave

Antwort

5

rspec Mocks und Stubs können für jede Klasse verwendet werden. Zum Beispiel:

coinbase_mock = double(api_key: ENV['COINBASE_KEY'], api_secret: ENV['COINBASE_SECRET']) 
expect(Coinbase::Wallet::Client).to_receive(:new).and_return(coinbase_mock) 

dann können Sie hinzufügen, was Sie wollen auf die coinbase_mock so, dass es wie die Klasse quakt Sie brauchen ... :)

2

Sie ein Ruby-Struct wie diese verwenden:

Coinbase::Wallet::Client = Struct.new(:api_key, :api_secret) 
@client = Coinbase::Wallet::Client.new(ENV['COINBASE_KEY'], ENV['COINBASE_SECRET']) 
@client.api_key #=> whatever was in ENV['COINBASE_KEY'] 

passieren dann das Objekt in

Wenn Sie Verhalten auf sie benötigen, können Sie auch, dass wie diese:.

Coinbase::Wallet::Client = Struct.new(:api_key, :api_secret) do 
    def client_info 
    ## logic here 
    "info" 
    end 
end 

@client = Coinbase::Wallet::Client.new(ENV['COINBASE_KEY'], ENV['COINBASE_SECRET']) 
@client.client_info #=> "info" 
1

Bevorzugte RSpec (seit ver. 3) Stil würde

let(:coinbase_client) { instance_double(Coinbase::Wallet::Client) } 
# validates that mocked/stubbed methods present in class definitiion 

before do 
    allow(coinbase_client).to receive(:sell_price).and_return({"base"=>"BTC", "currency"=>"USD", "amount"=>"PRICE YOU PROVIDE"}) 
end 

docs about instance_double method

sein, während Sie coinbase_client als Konstruktionsparameter auf Ihre Klassen injizieren, die sie intern verwenden

oder wenn aus irgendwelchen Gründen können Sie nicht Dependency Injection verwenden zu können, könnte eine beliebige Instanz von Coinbase :: Wallet :: Client mit

Verwandte Themen