0

我正在 Rspec 中编写一些测试,并试图通过关联将 a 推carrier送到 a 。下面是我写的测试,但是我用箭头指示的行似乎没有通过。我意识到我已经嘲笑了运营商,但没有嘲笑用户,我想知道这是否会导致 HABTM 关联出现问题。这是问题还是我还缺少其他东西?我是嘲笑和存根的新手,但我会尽力而为!userhas_and_belongs_to_many

describe UsersController do
  describe 'get #add_carrier' do
    let(:user) { build(:approved_user) }

    let(:carrier) { mock_model(Carrier).as_null_object }
    before{ Carrier.stub(:find).and_return(carrier) }

    it 'associates the Carrier to the User' do
      expect(user.carriers).to eq []
      user.should_receive(:carriers).and_return([])
  --> (user.carriers).should_receive(:push).with(carrier).and_return([carrier])
      (user.carriers).push(carrier)
      (user.carriers).should include carrier
    end 
  end
end
4

1 回答 1

0

当您想要进行适当的单元测试并存根除被测方法之外的任何内容时,通常会使用存根。当您测试调用命令方法的方法(即具有一定影响的方法,例如更改某些数据或保存记录)并且您希望确保调用它时,通常使用模拟(带有期望的存根)。

这个特殊的测试,考虑到它在控制器中,似乎在错误的级别上测试东西——它测试的是方法内部的东西,而不是方法本身。看看rspec 文档

不知道您正在测试的代码,准确地确定如何测试有点棘手。#add_carrier 听起来像是一个应该简单地测试是否添加了运营商的方法,所以我们大概可以测试消息期望。这个测试似乎也在测试 getter 方法#carriers,这对于一个单元测试来说似乎有点多(但我完全理解将它放在那里的愿望)。

另请注意,分享您遇到的错误肯定会有所帮助。

无论如何,请尝试以下操作:

describe UsersController do
  describe 'get #add_carrier' do # Should this really be a GET?
    subject { get :add_carrier }

    let(:user) { build(:approved_user) }
    let(:carrier) { mock_model(Carrier).as_null_object }

    before do
      controller.stub(:user) { user }
      Carrier.stub(:find) { carrier }
    end

    it "associates the Carrier to the User" do
      user.carriers.should_receive(:push).with(carrier).and_call_original
      subject
      user.carriers.should include carrier
    end
  end
end

对 user.carriers 的原始值没有期望(应该在用户模型中测试)。对 push 如何工作的细节没有任何期望 - 再次,应该在其他地方进行测试。相反,只是确认调用了重要的命令消息。我不是 100% 肯定我们甚至应该做#and_call_original 并确认结果,因为这些是我们也可以在模型单元测试中测试的东西(Carrier#push 的结果),但为了安心,我在这里包括了。

请注意,这一切都是凭记忆写的,所以如果其中任何一个不起作用,请告诉我。

于 2013-09-01T06:43:43.190 回答