Ruby on rails 如何期望使用特定的ActiveRecord参数运行方法

Ruby on rails 如何期望使用特定的ActiveRecord参数运行方法,ruby-on-rails,unit-testing,activerecord,ruby-mocha,Ruby On Rails,Unit Testing,Activerecord,Ruby Mocha,在Rails 4.2上使用Mocha。 我正在测试一个方法,它应该使用正确的参数调用另一个方法。这些参数是它从数据库调用的ActiveRecord对象。以下是我测试的要点: UserMailer.expects(:prompt_champion).with(users(:emma), [[language, 31.days.ago]]).once 用户(:emma)和语言都是ActiveRecord对象 即使进行了正确的调用,测试也会失败,因为参数与预期不匹配。我认为这可能是因为每次从数据库中

在Rails 4.2上使用Mocha。 我正在测试一个方法,它应该使用正确的参数调用另一个方法。这些参数是它从数据库调用的ActiveRecord对象。以下是我测试的要点:

UserMailer.expects(:prompt_champion).with(users(:emma), [[language, 31.days.ago]]).once
用户(:emma)
语言
都是ActiveRecord对象

即使进行了正确的调用,测试也会失败,因为参数与预期不匹配。我认为这可能是因为每次从数据库中提取记录时,它都是一个不同的Ruby对象

我认为解决这个问题的一种方法是,看看我的代码中使用了什么方法来提取记录并存根该方法以返回mock,但我不想这样做,因为检索了一大堆记录,然后向下过滤以获得正确的记录,对所有这些记录进行mock会使测试方法变得过于复杂


有更好的方法吗?

您可以使用RSpec并比较该函数中的预期值。

您可以使用RSpec并比较该函数中的预期值。

您可以使用allow/expect的块形式

expect(UserMailer).to receive(:prompt_champion) do |user, date|
  expect(user.name).to eq "Emma"
  expect(date).to eq 31.days.ago # or whatever
end

您可以使用allow/expect的块形式

expect(UserMailer).to receive(:prompt_champion) do |user, date|
  expect(user.name).to eq "Emma"
  expect(date).to eq 31.days.ago # or whatever
end

塞吉奥给出了最好的答案,我接受了。我独立地找到了答案,并在一路上发现我需要从ActionMailer方法返回一个mock,以使一切正常工作

我想最好把我的完整测试贴在这里,为了其他不幸的冒险家。我用的是Minitest-Spec

it 'prompts champions when there have been no edits for over a month' do
    language.updated_at = 31.days.ago
    language.champion = users(:emma)
    language.save
    mail = mock()
    mail.stubs(:deliver_now).returns(true)
    UserMailer.expects(:prompt_champion).with do |user, languages|
        _(user.id).must_equal language.champion_id
        _(languages.first.first.id).must_equal language.id
    end.once.returns(mail)
    Language.prompt_champions
end

塞吉奥给出了最好的答案,我接受了。我独立地找到了答案,并在一路上发现我需要从ActionMailer方法返回一个mock,以使一切正常工作

我想最好把我的完整测试贴在这里,为了其他不幸的冒险家。我用的是Minitest-Spec

it 'prompts champions when there have been no edits for over a month' do
    language.updated_at = 31.days.ago
    language.champion = users(:emma)
    language.save
    mail = mock()
    mail.stubs(:deliver_now).returns(true)
    UserMailer.expects(:prompt_champion).with do |user, languages|
        _(user.id).must_equal language.champion_id
        _(languages.first.first.id).must_equal language.id
    end.once.returns(mail)
    Language.prompt_champions
end