簡體   English   中英

如何使用Rspec和Rails模擬一個類?

[英]How do I mock a class using Rspec and Rails?

我正在使用Rails 5和Rspec 3.如何在Rspec方法中模擬一個類? 我有以下課程

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

而不是實際實例化行中的“Coinbase :: Wallet”類

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

我想創建mock taht然后我可以插入到我正在測試的服務類中。 就目前而言,當我運行時,實際的底層類被實例化,導致運行時錯誤...

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

     Coinbase::Wallet::AuthenticationError:
       invalid api key

rspec模擬和存根可以在任何類上使用。 例如:

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

然后你可以添加你喜歡的任何東西到coinbase_mock這樣它就像你需要的類一樣coinbase_mock ... :)

您可以像這樣使用Ruby Struct:

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']

然后傳遞該對象。

如果你需要它的行為,你也可以這樣:

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"

首選的RSpec(自第3版)風格

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

有關instance_double方法的文檔

當你將coinbase_client作為構造參數注入到內部使用它的類時

或者如果由於某些原因你不能使用依賴注入,你可以模擬Coinbase :: Wallet :: Client的任何實例

allow_any_instance_of(Coinbase::Wallet::Client).to receive(... *mock specific method*)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM