【问题标题】:Testing Creation Variable Assignments in Rspec在 Rspec 中测试创建变量分配
【发布时间】:2012-10-30 05:55:47
【问题描述】:

我正在创建一个 rspec 测试来查看 create 方法中的实例变量是否保留了构建的数据。但是,我的测试不起作用,因为我返回此错误...

Failure/Error: assigns[:micropost]should eq(@post)
expected: #<Micropost id: 1, content: "Hello there", user_id: 1>
got: #<Micropost id: 2, content: "Hello there", user_id: 1>

我的 rspec 测试是

describe ::MicropostsController do

before :each do
  @post = FactoryGirl.create(:micropost)
end

it "tests the instance variable in create method" do
    post :create, micropost: FactoryGirl.attributes_for(:micropost)
    assigns(:micropost).should eq(@post)
end

我的 FactoryGirl 文件是

FactoryGirl.define do

 factory :micropost do

  content "Hello there Bob!"
  user_id "1"
  #even if I got rid of the double quotations around 1, the stringify key error still 
  #pops up

 end

end

这里是微柱控制器创建动作代码...

def create

@micropost = Micropost.new(params[:micropost])

 respond_to do |format|

  if @micropost.save

    format.html { redirect_to @micropost, notice: 'Micropost was successfully create.' 
    }

  else

    format.html { render action: "new" }

  end

 end

end

【问题讨论】:

  • 我已经用你的控制器代码编辑了我的答案

标签: ruby-on-rails ruby-on-rails-3 testing rspec


【解决方案1】:

如果您想测试微帖子是否已创建,您必须将一些参数传递给帖子操作,在您的测试中,您只需构建一个新的微帖子(在内存中,未保存),您的创建操作甚至不知道它存在:

我应该这样做:

before(:each) do
  @micro_mock = mock(:micropost)
  @micro_mock.stub!(:save => true)
end

it "creates a micropost" do
  params = {:micropost => {:something => 'value', :something2 => 'value2'}}
  Micropost.should_receive(:new).with(params).and_return(@micro_mock)
  post :create, params
end

it "assigns the created micropost to an instance variable" do
  Micropost.stub!(:new => @micro_mock)
  post :create
  assigns(:micropost).should == @micro_mock
end

您应该测试重定向和闪存消息到(需要时将保存方法存根为真/假)

【讨论】:

  • 是否需要模拟?我不能坚持使用 FactoryGirl 吗?我再次更新了代码。这次我得到的和预期的一样,只是 id 减了 1。
  • 你可以使用FactoryGirl,但是你的测试会慢一些,在数据库上创建一个真正不需要的对象(你的控制器并没有真正创建对象,它只调用Micropost的新方法,你应该测试一下)。我使用 FactoryGirl 进行了很多控制器测试,然后将所有内容都替换为模拟,并且测试运行时间不到一半。查看此样式指南以获取更多信息github.com/bbatsov/rails-style-guide#rspec
  • 您的测试因 ID 失败,因为您在 before 块上创建一个对象,然后在控制器上创建另一个对象,然后您有 2 个不同的对象。您至少应该存根新方法 Micropost.stub!(:new => @post) 以便获得完全相同的对象,但同样,由于您存根新方法不需要 Micropost 对象,您可以使用那里有一个模拟。
  • 您的帮助非常大。感谢您对我的时间和耐心。我还将查看您发布的样式指南。再次感谢!!!
【解决方案2】:

micropost 中的值为零,因为您没有在此行中发布任何数据:

post '/microposts'

您需要实际包含数据才能使其工作:

post '/microposts', :micropost => p

【讨论】:

  • 我返回了以下错误NoMethodError: undefined method 'stringify_keys' for "#&lt;Micropost:4asdfsa23&gt;":String
  • 你的微贴工厂有什么?看起来你正在返回一个字符串......
  • 抱歉,请尝试将assigns[:micropost] 切换为assigns(:micropost)
  • 属性还是nil吗?您可以发布create 操作的控制器代码吗?
  • 在问题中发布了更新的代码和控制器代码。该错误当前期待 FactoryGirl 微博,但得到一个所有属性为 nil 的微博。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-12-13
  • 2012-10-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-09-01
  • 1970-01-01
相关资源
最近更新 更多