相互依赖并使用gem的模型方法的Rspec

时间:2019-01-12 01:24:50

标签: ruby-on-rails rspec

在我的RSpec旅程中,我想从用户模型中测试3种方法,每种方法都相互依赖。它们是宝石stock_qoute的某种帮助方法,仅检查是否已将搜索项目(库存)添加到投资组合中,或者用户是否已达到添加项目的限制(10个库存)。这些方法是在视图中使用的。

我试图嘲笑这个宝石,但我认为这不是最简单的方法。我想我可以跳过整个gem,而只使用变量,但是我不知道该怎么做。我正在使用没有FactoryBot的devise和Rspec。

user.rb

has_many :user_stocks
has_many :stocks, through: :user_stocks

def stock_already_added?(ticker_symbol)
 stock = Stock.find_by_ticker(ticker_symbol)
 return false unless stock

 user_stocks.where(stock_id: stock.id).exists?
end

def under_stock_limit?
 (user_stocks.count < 10)
end

def can_add_stock?(ticker_symbol)
 under_stock_limit? && !stock_already_added?(ticker_symbol)
end

来自不同模型的find_by_ticker方法:

def self.find_by_ticker(ticker_symbol)
 where(ticker: ticker_symbol).first
end

查看文件:

  <% if current_user.can_add_stock?(@stock.ticker) %>
      <%= link_to 'Add stocks', user_stocks_path(user: current_user, stock_ticker: @stock.ticker),
                                              class: 'btn btn-xs btn-success', method: :post %>
    <% else %>
      <span class="label label-default">
        Stock cannot be added because you have added
        <% if !current_user.under_stock_limit? %>
        10 stocks
        <% end %>
        <% if current_user.stock_already_added?(@stock.ticker) %>
          this stock
          <%= link_to 'Remove', user_stock_path, method: :delete %>
        <% end %>
      </span>
    <% end %>

user_spec.rb:

  describe 'Add stock' do
    user = User.create(email: 'test@example.com', password: 'password')

    context 'when user add the same stock' do
      let(:stock) { Stock.new(name: 'Goldman Sachs', ticker: 'GS', last_price: 112.4) }

      it "return false" do
        user_stocks = UserStock.new(user: user, stock: stock)
        expect(user_stocks.can_add_stock?('GS')).to eq false
      end
    end
  end

现在我有一个错误:

  

1)用户添加相同库存时用户添加库存返回false        失败/错误:期望(user_stocks.can_add_stock?('GS'))。等于真

NoMethodError:
  undefined method `can_add_stock?' for #<UserStock:0x00007fb0efa4d3a8>
# ./spec/models/user_spec.rb:29:in `block (4 levels) in <top (required)>'

1 个答案:

答案 0 :(得分:0)

当它是User模型的方法时,为什么要在user_stock上调用can_add_stock??您需要检查用户的库存

describe 'Add stock' do
  let(:user) { User.create(email: 'test@example.com', password: 'password') }

  context 'when user add the same stock' do
    let(:stock) { Stock.create(name: 'Goldman Sachs', ticker: 'GS', last_price: 112.4) }

    it "return false" do
      user.stocks << stock
      expect(user.can_add_stock?('GS')).to eq false
    end
  end
end