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

时间:2017-10-23 15:12:59

标签: ruby-on-rails unit-testing activerecord mocha

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

UserMailer.expects(:prompt_champion).with(users(:emma), [[language, 31.days.ago]]).once

users(:emma)language都是ActiveRecord对象。

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

我认为解决这个问题的一种方法是看看我的代码中使用了什么方法来提取记录并将该方法存根以返回模拟,但我不想这样做,因为检索了大量的记录然后过滤下来以找到正确的,模拟所有这些记录会使测试方式过于复杂。

有更好的方法吗?

3 个答案:

答案 0 :(得分:1)

您可以使用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

答案 1 :(得分:0)

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

答案 2 :(得分:0)

Sergio给出了最好的答案,我接受了。我独立地发现了答案,并且发现我需要从ActionMailer方法返回一个模拟以使一切正常工作。

我认为最好在这里发布我的完整测试,以便任何其他不幸的冒险家来这里。我正在使用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