ruby-on-rails - 我是否需要在此测试中创建每个对象?

标签 ruby-on-rails ruby-on-rails-3 testing ruby-on-rails-3.2

我的测试是这样的:

def setup
    @period_registration= FactoryGirl.create(:period_registration)
  end


 test "should post save_period" do
    sign_in(FactoryGirl.create(:user))
     assert_difference('PeriodRegistration.count') do
      post :save_period, period_registration: FactoryGirl.attributes_for(:period_registration)
    end
    assert_not_nil assigns(:period_registration)

  end

但是当我运行它时,我得到了这个错误:

 1) Error:
test_should_post_save_period(PeriodRegistrationsControllerTest):
NoMethodError: undefined method `event' for nil:NilClass

这是我的 Controller :

  def save_period
    @period_registration = PeriodRegistration.new(params[:registration])
    @period_registration.save
    flash[:success] = "Successfully Registered for Session."
    redirect_to event_url(@period_registration.period.event)
  end

我的工厂是这样的:

factory :event do
    name 'First Event'
    street '123 street'
    city 'Chicago'
    state 'Iowa'
    date Date.today
  end


  factory :period do
    name 'First Period'
    description 'This is a description'
    start_time Time.now + 10.days
    end_time Time.now + 10.days + 2.hours
    event
    product
  end

factory :period_registration do
    user
    period
  end

我需要创建一个周期对象和一个事件对象吗?如果是这样怎么办?我不认为这是问题所在,因为我相信通过在各个工厂中设置“期间”、“产品”和“事件”会自动创建这些。

关于从这里看哪里有什么想法吗?

最佳答案

简短的回答 - 是的,您确实创建了对象。

长答案:

  1. 在 Controller 中:

    @period_registration.period.event
    

    这行代码违反了The Law Of Demeter .这不是好的设计。这行代码应该如下所示:

    @period_registration.event
    

    但是您必须在 PeriodRegistration 模型中创建新方法。最简单的方法变体可以是:

    def event
      period.event
    end
    
  2. 在 Controller 中:您不检查 PeriodRegistration 模型是否已保存。

  3. 据我了解,PeriodRegistration 模型有 2 个关联,当您使用 FactoryGirl.attributes_for 时,工厂不会创建关联对象,它只会为您提供 PeriodRegistration 的一组属性。为了使这个测试通过,你应该在调用 Controller 之前创建这两个对象。最好的做法是——测试应该只有一个断言。例如:

    def setup
      @user = FactoryGirl.create(:user)
      @period = FactoryGirl.create(:period)
    end
    
    test "should post save_period" do
      sign_in(@user)
      assert_difference('PeriodRegistration.count') do
        post :save_period, period_registration: FactoryGirl.attributes_for(:period_registration, user: @user, period: @period)
      end
    end
    
    test "should assings @period_registration" do
      sign_in(@user)
      post :save_period, period_registration: FactoryGirl.attributes_for(:period_registration, user: @user, period: @period)
      assert_not_nil assigns(:period_registration)
    end
    
  4. 测试 Controller 时,您可以使用模拟对象而不是真实模型。

关于ruby-on-rails - 我是否需要在此测试中创建每个对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12220719/

相关文章:

java - Mockito 测试 RestClient aSync

ruby-on-rails - 目录 : template missing error while rendering JSON

ruby-on-rails - deliver_later 不重试

python - Rails 应用程序中 Ruby 子外壳中的引用文件

ruby-on-rails - RSPEc - #<RoomsController :0x0000010534c050> 的未定义方法 `stubs'

ruby-on-rails - js.erb 文件中的 if 语句基于 param_name will_paginate (Ajax 调用)

reactjs - 错误 : Unable to find an element with the text when I try a test with Jest in React

ruby-on-rails - 如何使用 Rails 查找动态定义的方法

ruby-on-rails - 限制mongoid中的版本属性

unit-testing - 使用 NUnit 插件在 TeamCity 6.5.X 中运行 NUnit 测试