Home > OS >  How do you test that a method is called inside a method call block, and what is passed to that metho
How do you test that a method is called inside a method call block, and what is passed to that metho

Time:11-04

This is the code that I am trying to test:

Appsignal.send_error(error) do |transaction|
  transaction.set_tags({
    customer_communication_id: customer_communication_id,
    interaction_reason_id: interaction_reason_id,
  })
end

I want to test three things:

  1. That the error is getting passed.
  2. That set_tags is getting call in the block.
  3. That the correct tags are getting set in the set tags call.

For test #1:

expect(Appsignal).to receive(:send_error).with(an_instance_of(ActiveRecord::RecordNotFound))

This is working as expected.

I have tried a few things, but have no idea how to test 2 & 3. On #3 I would want to test the tags are correct with something like:

hash_including(customer_communication_id: customer_communication.id, interaction_reason_id: InteractionReason::PAYMENT_REMINDER_TEXT.id)

CodePudding user response:

Regarding 2: use test double, something like (pseudocode)

transaction = instance_double(<whatever class it is expected to be>)
allow(Appsignal).to receive(:send_error).and_yield(transaction)
allow(transaction).to receive(:set_tags)

<do something>

expect(Appsignal)
  .to have_received(:send_error)
  .with(<expected error>)

expect(transaction)
  .to have_received(:set_tags)
  .with(
    customer_communication_id: customer_communication_id, 
    interaction_reason_id: interaction_reason_id
  )

Regarding 3: decouple, set_tags should be tested in isolation, not with 1 and 2. Just cover it with good unit tests if it is your code (or ignore if it is provided by the 3rd party library - it is supposed to be tested by the 3rd party tests; well, hopefully :))

  • Related