Rails 集成测试 - nil:NilClass 的未定义方法 - 在产品中有效

Rails integration test - undefined method for nil:NilClass - works in prod

我正在学习 Michael Hartl 的教程(添加了一些自定义内容,以便我了解更多信息),尽管如此,我 运行 在我的 运行 测试期间遇到了以下错误似乎在生产中工作正常。每个用户可以有多个亲戚。

RelativesNewTest#test_valid_submission:

app/views/relatives/show.html.erb:38:in 'block in _app_views_relatives_show_html_erb__4581323407307698757_68563600'

app/views/relatives/show.html.erb:30:in '_app_views_relatives_show_html_erb__4581323407307698757_68563600'

test/integration/relatives_new_test.rb:47:in 'block in class:RelativesNewTest'

相关型号:

class Relative < ApplicationRecord
  belongs_to :user
  has_one :state
  has_one :relation

  validates :user_id, :name, presence: true

State 和 Relation 表只有 id 和 name 列。

相对控制器:

class RelativesController < ApplicationController
  before_action :setup

  def setup
    @user = current_user
    @relatives = current_user.relatives.all
  end

  def index
  end

  def show
  end

  def new
    @relative = Relative.new
  end

  def create
    @relative = current_user.relatives.build(relative_params)
    if @relative.save
      redirect_to relatives_path
    else
      render 'new'
    end
  end

  def edit
    @relative = current_user.relatives.find(params[:id])
  end

  def update
    @relative = current_user.relatives.find(params[:id])
    if @relative.update_attributes(relative_params)
      redirect_to relatives_path
    else
      render 'edit'
    end
  end

  def destroy
    @relative = current_user.relatives.find(params[:id])
    @relative.destroy
    flash[:success] = "Relative deleted"
    redirect_to relatives_path
  end

  private

  def relative_params
    params.require(:relative).permit(:name, :relation_id, :email, :phone, :street, :unit, :city, :state_id, :zip)
  end
end

观点:

<% @relatives.each do |relative| %>
  <div id="relative_<%= relative.id %>" class="row row-lines">
    <div class="col-md-2 col-sm-4 col-xs-12 form-group">
      <p id="name" class="form-control"><%= relative.name %></p>
    </div>
    <div class="col-md-1 col-sm-2 col-xs-12 form-group">
      <p id="relation" class="form-control">
      <% unless relative.relation_id.nil? %>
        <%= Relation.find_by_id(relative.relation_id).name %>
      <% end %></p>
    </div>

错误中引用的行是 <% @relatives.each do |relative| %><%= Relation.find_by_id(relative.relation_id).name %>。这一切(显示、新建、编辑)在生产中工作正常。

测试:

require 'test_helper'

class RelativesNewTest < ActionDispatch::IntegrationTest

  def setup
    @user = users(:testuser)
  end

  test "valid submission" do
    log_in_as(@user)
    get relatives_new_path
    assert_difference 'Relative.count', 1 do
      post relatives_new_path params: {relative: {
        name: 'First Relative',
        relation_id: 1,
        street: '123 Fake Street',
        city: 'Philadelphia',
        state_id: 39,
        zip: 12345}}
    end
    assert_not flash.empty?
    assert_redirected_to relatives_path
    follow_redirect!
    assert_select 'p#name', 'First Relative'
  end
end

错误中引用的测试行是 follow_redirect!。该视图在生产中运行良好,显示关联的关系名称。我必须考虑的测试中的重定向和变量有什​​么独特之处吗?

我认为在您的测试中您需要创建一个 ID 为 1 的关系(在您 post relatives_new_path 之前),因为您在 Relative 创建中引用了它。

name: 'First Relative',
relation_id: 1,

或者你可以做类似

relation = new Relation
log_in_as(@user)
get relatives_new_path
assert_difference 'Relative.count', 1 do
  post relatives_new_path params: {relative: {
    name: 'First Relative',
    relation_id: relation.id,