0

Using Mocha on Rails 4.2. I'm testing a method that it should make a call to another method with the correct parameters. These parameters are ActiveRecord objects that it calls up from the database. Here is the key line in my test:

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

Both users(:emma) and language are ActiveRecord objects.

Even though the correct call is made, the test fails because the parameters don't match the expectations. I think this might be because it's a different Ruby object each time a record is pulled up from the database.

I think one way around it is to see what method is being used in my code to pull up the records and stub that method to return mocks, but I don't want to do this because a whole bunch of Records are retrieved then filtered down to get to the right one, mocking all those records would make the test way too complex.

Is there a better way of doing this?

Machavity
  • 30,841
  • 27
  • 92
  • 100
Toby 1 Kenobi
  • 4,717
  • 2
  • 29
  • 43

3 Answers3

1

You could use block form of 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
Sergio Tulentsev
  • 226,338
  • 43
  • 373
  • 367
1

Sergio gave the best answer and I accepted it. I discovered the answer independently and found out along the way that I needed to return a mock from the ActionMailer method to make everything work properly.

I think it best to post here my complete test here for the sake of any other hapless adventurer to come this way. I'm using 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
Toby 1 Kenobi
  • 4,717
  • 2
  • 29
  • 43
0

You could use an RSpec custom matcher and compare expected values in that function.

Tom Copeland
  • 1,221
  • 10
  • 10