You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

RSpec控制器测试失败:Buy交易状态未更新为done求助

Troubleshooting RSpec Test Failure: buy.trading_status Remains "pending" Instead of "done"

Let's break down your issue and walk through actionable fixes to get your test passing:

Problem Recap

You're trying to verify that the #new action in your BuysController properly executes database changes, but your test is failing with:

  • A "no save" message (confirming buy.save failed)
  • An expectation mismatch: expected buy.trading_status to be "done", got "pending"

You’ve already tried running rake db:test:prepare and RAILS_ENV=test rake db:migrate without resolving the issue.

Key Issues in Your Test Code

Let’s unpack why your test isn’t behaving as expected:

  1. You’re not actually testing the controller’s #new action
    Your test manually creates a Buy instance and calls market_checker outside the controller’s context. This doesn’t replicate what happens when a user hits the #new route—you need to trigger the controller action directly to test its logic.

  2. Hardcoded IDs are causing save failures
    You’re manually setting id:1 for both Sell and Buy. If your test database has leftover data (or the primary key sequence isn’t reset), this will trigger a duplicate primary key error, which is why buy.save is failing (hence the "no save" log).

  3. Uncertainty whether market_checker persists changes
    If your helper only updates the trading_status attribute without calling save on the buy instance, the change won’t be written to the database.

  4. Potential confusion between #new and #create actions
    In Rails convention, #new is a GET action that renders a creation form, while #create is the POST action that processes and saves the record. Double-check which action contains your database modification logic.

Step-by-Step Fixes

1. Diagnose the Exact Cause of the Save Failure

First, add error logging to see why buy.save is failing. Modify your test’s else block:

else
  p "no save"
  p buy.errors.full_messages # This will show validation/database errors
end

Running the test again will reveal if it’s a validation issue, duplicate ID, missing required fields, etc.

2. Rewrite the Test to Target the Controller Action

Instead of manually creating a Buy instance, trigger the controller action and check the actual database record. Here’s a revised test (assuming your logic lives in #create—adjust if it’s truly in #new):

require 'rails_helper'
include BuysHelper

RSpec.describe BuysController, type: :controller do
  describe "POST #create" do
    it "sets buy's trading_status to 'done' after creation" do
      # Create dependencies without hardcoding IDs
      user = User.create!(name: "hhhvv", email: "gggjggg@gmail.com")
      currency = Currency.create!(name: "hello", user_id: user.id)
      Sell.create!(user_id: user.id, currency_id: currency.id, amount: 100, price: 100, trading_status: "pending")
      
      # Trigger the controller's create action with valid params
      post :create, params: { 
        buy: { 
          user_id: user.id, 
          currency_id: currency.id, 
          amount: 100, 
          price: 100, 
          trading_status: "pending" 
        } 
      }
      
      # Fetch the created buy from the database (not the in-memory instance)
      created_buy = Buy.last
      expect(created_buy.trading_status).to eq("done")
    end
  end
end

3. Ensure market_checker Persists Changes

Verify your helper method actually saves the trading_status update. For example:

# In buys_helper.rb
def market_checker(buy)
  buy.trading_status = "done"
  buy.save! # Use save! to raise an error if save fails (easier debugging)
end

If you’re not passing the buy instance to the helper, or modifying a copy instead of the original, the change won’t stick.

4. Reset Your Test Database

Leftover data can cause unexpected conflicts. Reset the test database to a clean state:

RAILS_ENV=test rake db:reset

This drops, recreates, migrates, and seeds (if applicable) the test database, ensuring no residual data interferes with your tests.

Final Tips

  • Avoid hardcoding IDs in tests—let Rails handle primary key generation to prevent conflicts.
  • Use create! instead of create in tests (it raises an error if creation fails, speeding up debugging).
  • Confirm you’re testing the correct controller action (don’t mix up #new and #create).

内容的提问来源于stack exchange,提问作者Ryu Nishida

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 03:42:15