gpt4 book ai didi

ruby-on-rails - Rspec 让变量产生奇怪的结果

转载 作者:行者123 更新时间:2023-12-04 06:19:18 24 4
gpt4 key购买 nike

我对 RSpec 有一个奇怪的问题,我不太明白。

这是我的port_stock_spec.rb文件:

# == Schema Information
#
# Table name: port_stocks
#
# id :bigint(8) not null, primary key
# portfolio_id :integer
# stock_id :integer
# volume :integer
# transaction_price :float
# current_price :float
# percent_change :float
# created_at :datetime not null
# updated_at :datetime not null
# current_value :float
# dollar_change :float
# total_spend :float
# transaction_date :datetime
# action :integer
# position :integer default("open")
# ticker :string
# slug :string
#

require 'rails_helper'

RSpec.describe PortStock, type: :model do
let(:stock) { create(:stock, price: 10.00) }
let(:portfolio) { create(:portfolio) }
let(:port_stock_1) { create(:port_stock, stock: stock, portfolio: portfolio, transaction_price: stock.price, action: :buy, volume: 100) }

context "associations" do
it { should belong_to(:portfolio) }
it { should belong_to (:stock) }
end

context "methods" do
it "should accurately calculate the positive percent_change of the current PortStock" do
port_stock_1.current_price = 20.00
expect(port_stock_1.calculate_percent_change).to eql 100.00
end

it "should accurately calculate the negative percent_change of the current PortStock" do
port_stock_1.current_price = 5.00
expect(port_stock_1.calculate_percent_change).to eql(-50.00)
end

it "should accurately calculate the negative dollar_change of the current PortStock" do
port_stock_1.current_price = 5.00
port_stock_1.volume = 1000
expect(port_stock_1.calculate_dollar_change).to eql (-5000.00)
end

# more specs that may or may no interact with the let variables.

it "should accurately calculate the portfolio's initial_dollar_value" do
expect(portfolio.initial_dollar_value).to eql 1000.00
end

结尾

然后我的 portfolio.rb 上有以下方法模型:
  def calculate_portfolio_initial_dollar_value
if self.portfolio.initial_dollar_value.nil?
self.portfolio.initial_dollar_value = 0.0
end
self.portfolio.initial_dollar_value += (self.transaction_price * self.volume)
self.portfolio.save!
end

当我运行我的测试套件时,最后一个测试一直失败,但它不应该:
Failures:

1) PortStock methods should accurately calculate the portfolio's initial_dollar_value
Failure/Error: expect(portfolio.initial_dollar_value).to eql 1000.00

expected: 1000.0
got: 798229.0

(compared using eql?)
# ./spec/models/port_stock_spec.rb:77:in `block (3 levels) in <top (required)>'

Finished in 5.05 seconds (files took 3.68 seconds to load)
29 examples, 1 failure, 19 pending

所以我放了一个 binding.pryit 内最后几个测试的 block 以及当我检查 portfolio.initial_dollar_value 时它反复更改值。
[1] pry(#<RSpec::ExampleGroups::PortStock::Methods>)> portfolio
=> #<Portfolio:0x00007fcdc5c5db28
id: 14,
user_id: 7,
current_dollar_value: 2864770.0,
percent_change: 75.02,
created_at: Sat, 13 Apr 2019 00:36:24 UTC +00:00,
updated_at: Sat, 13 Apr 2019 00:36:24 UTC +00:00,
num_winners: 2,
num_losers: 7,
initial_dollar_value: 860679.0,
dollar_change: 92865.0>
[2] pry(#<RSpec::ExampleGroups::PortStock::Methods>)> port_stock_1.portfolio
=> #<Portfolio:0x00007fcdc5c5db28
id: 14,
user_id: 7,
current_dollar_value: 150.0,
percent_change: -85.0,
created_at: Sat, 13 Apr 2019 00:36:24 UTC +00:00,
updated_at: Sat, 13 Apr 2019 00:36:42 UTC +00:00,
num_winners: 0,
num_losers: 1,
initial_dollar_value: 1000.0,
dollar_change: -850.0>
[3] pry(#<RSpec::ExampleGroups::PortStock::Methods>)> portfolio
=> #<Portfolio:0x00007fcdc5c5db28
id: 14,
user_id: 7,
current_dollar_value: 150.0,
percent_change: -85.0,
created_at: Sat, 13 Apr 2019 00:36:24 UTC +00:00,
updated_at: Sat, 13 Apr 2019 00:36:42 UTC +00:00,
num_winners: 0,
num_losers: 1,
initial_dollar_value: 1000.0,
dollar_change: -850.0>
[4] pry(#<RSpec::ExampleGroups::PortStock::Methods>)> portfolio
=> #<Portfolio:0x00007fcdc5c5db28
id: 14,
user_id: 7,
current_dollar_value: 150.0,
percent_change: -85.0,
created_at: Sat, 13 Apr 2019 00:36:24 UTC +00:00,
updated_at: Sat, 13 Apr 2019 00:36:42 UTC +00:00,
num_winners: 0,
num_losers: 1,
initial_dollar_value: 1000.0,
dollar_change: -850.0>
[5] pry(#<RSpec::ExampleGroups::PortStock::Methods>)>

我不明白为什么。

想法?

编辑 1

这是 portfolio.rb工厂:
FactoryBot.define do
factory :portfolio do
user
current_dollar_value { Faker::Number.number(7) }
percent_change { Faker::Number.decimal(2) }
num_winners { Faker::Number.number(1) }
num_losers { Faker::Number.number(1) }
initial_dollar_value { Faker::Number.number(6) }
dollar_change { Faker::Number.number(5) }
end
end

编辑 2

我的 port_stock.rb 上有一个回调触发与 portfolio_initial_dollar_value 相关的方法的模型:
after_save :calculate_portfolio_initial_dollar_value

还有其他影响投资组合其他方面的回调:
  after_save :update_portfolio_current_dollar_value
after_save :update_portfolio_initial_dollar_value, if: (:total_spend_previously_changed? || :volume_previously_changed?)

def update_portfolio_current_dollar_value
self.portfolio.current_dollar_value = self.portfolio.port_stocks.open.map(&:current_value).sum
self.portfolio.save!
end

def update_portfolio_initial_dollar_value
self.portfolio.initial_dollar_value = self.portfolio.port_stocks.open.map { |ps| ps.volume * ps.transaction_price }.sum
self.portfolio.save!
end

编辑 3

对于模型( port_stock.rb )和规范( port_stock_spec.rb )文件的完整版本,请查看 out this gist .我不想用那个完整的转储污染 SO。

最佳答案

正如@grzekos 指出的那样,在执行 stock 测试期间,您永远不会调用 port_stock_1it "should accurately calculate the portfolio's initial_dollar_value"

为什么?因为您使用 let 来设置/创建测试对象。
如果您想始终设置/创建 stockportfolioport_stock_1 ,您可以使用 let! ( RSpec documentation ) 或使用 before block ,如下所示:

let(:stock) { create(:stock, price: 10.00) }
let(:portfolio) { create(:portfolio) }
let(:port_stock_1) { create(:port_stock, stock: stock, portfolio: portfolio, transaction_price: stock.price, action: :buy, volume: 100) }

before do
stock
portfolio
port_stock_1
end

为什么在使用 pry 进行调试时会看到不同的数字?

在您的第一个测试中,您调用了使用 FactoryBot 创建的 portfolio 对象。工厂通过 initial_dollar_valueFaker::Number.number(6) 属性分配了一个随机的 6 位数字。

在您的第二个测试中,您调用了 port_stock_1.portfolio 。现在对 let(:port_stock_1) block 进行评估。这将创建一个 PortStock 对象,该对象在其 after_save 方法中更新 initial_dollar_valueportfolio
portfolioport_stock_1.portfolio 的所有子序列调用不再更改 initial_dollar_value 的值。

关于ruby-on-rails - Rspec 让变量产生奇怪的结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55661392/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com