ruby-on-rails - 通过模拟测试两种不同的期望

标签 ruby-on-rails ruby rspec rspec2 ruby-mocha

我最近刚刚将 Devise 添加到我的第一个 Rails3 应用程序中,但我在 Controller 测试方面遇到了一些麻烦。

我正在测试用户 Controller 类,它与 Devise 使用的模型相同。所以在我的规范开始时我有这个:

before(:each) do
  sign_in @user = Factory.create(:user)
end

现在我可以让测试通过,而无需像这样使用模拟或 stub :

describe "GET edit" do
  it "assigns the requested user as @user" do
    user = Factory(:user)
    get :edit, :id => user.id
    assigns(:user).should eql(user)
  end
end

但出于教育目的,我想知道如何让它与 mocking 和 stubbing 一起工作,通常它是完全直接的,但似乎 Devise 在 Controller 之前调用 User.find行动,并使测试失败。

describe "GET edit" do
  it "assigns the requested user as @user" do
    user = Factory(:user)
    User.expects(:find).with(:first, :conditions => {:id => 37}).returns(user)
    get :edit, :id => '37'
    assigns(:user).should be(user)
  end
end

此外,通过将 twice 添加到期望中,这也会失败,因为第一次调用 find 与我设置期望的调用不同。

如有任何见解,我们将不胜感激。

最佳答案

您可以使用 stubsexpects 指定多个返回值,如下所示:

require 'test/unit'
require 'mocha'

class Foo
end

class FooTest < Test::Unit::TestCase

  # This passes!
  def test_multiple_returns_with_stubs
    Foo.stubs(:find).returns('a').returns('b').returns('c')

    assert_equal('a', Foo.find('z'))
    assert_equal('b', Foo.find('y'))
    assert_equal('c', Foo.find('x'))
  end

  # This passes too!
  def test_multiple_returns_with_expects
    Foo.expects(:find).times(1..3).returns('a').returns('b').returns('c')

    assert_equal('a', Foo.find('z'))
    assert_equal('b', Foo.find('y'))
    assert_equal('c', Foo.find('x'))
  end
end

显然,区别在于 expects 需要知道它将被调用多少次。如果您未指定任何内容,它会假定 一次 并将在后续调用中提示。 stubs 不关心。

关于ruby-on-rails - 通过模拟测试两种不同的期望,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3353287/

相关文章:

ruby-on-rails - 如何跟踪一个用户在线的时间?使用 Ruby on Rails

ruby - 登录时启动脚本

css - Ruby:解析明文的结构化 block

ruby-on-rails - RSpec:测试范围预加载

ruby-on-rails - Rspec Postgres 错误

ruby-on-rails - 在 Ruby 中对嵌套/邻接模型进行排序的算法

ruby-on-rails - 未定义的方法 'should' 将 Capybara 与 Cucumber 一起使用时

ruby-on-rails - 弹性-QueryingParsingException-查询不支持-使用过滤器按关联字段搜索时

ruby-on-rails - 如何让 Rails View 返回其关联的操作名称?

ruby-on-rails - 在 factorybot 中附加 ActiveStorage 文件