0

I have a controller action which calls a spawn block

class MyController <  ApplicationController
  ....
  def send_product_mails
    if @user.has_rights?
        spawn_block(:nice => 19 ) do 
          @current_product.send_mail
        end
    end
  end
  ...
end

and I want to spec thet send_mail is called on @current_product, but it tells me it didn't receive it.. How should one do it?

My Spec looks like so:

it "works with spawn" do
  # Setup: create Product, Usersession (via UserSession.create(user))
  get :send_product_mails, :id => product.id
  MyController.any_instance.should_receive(:spawn_block).and_yield("sd")
end

I want to spec that something is passed to the spawn_block if the user has the rights, and nothing otherwise. Right now with different trys (calling .should_receive in the test on MyController, MyController.any_instance, @controller, with or without and_yield this always gives errors that the message spawn_block wasn't received. (Yes, I checked that the rights are acutally okay by adding a puts-debug-output within the if-statement.)

EDIT: Gave more context and code to the question, and what I've tried

Yo Ludke
  • 2,149
  • 2
  • 23
  • 38
  • I'm not sure you'll be able to do this without stubbing spawn_block - your should_receive isn't going to work cross-process – Frederick Cheung Apr 03 '13 at 16:17
  • okay so I do something like `MyController.should_receive(:spawn_block)`.. but this doesn't work, how should I do it? – Yo Ludke Apr 05 '13 at 08:42
  • You'd to use and_yield so that your block is executed – Frederick Cheung Apr 05 '13 at 08:46
  • @FrederickCheung The problem lies deeper I suppose, the error messages are `Exactly one instance should have received the following message(s) but didn't: spawn_block` or `().spawn_block(any args) expected: 1 time received: 0 times` So it doesn't see it's received in the first place – Yo Ludke Apr 05 '13 at 11:04
  • well you need to be calling should _receive on the instance of the controller, not on the class (unless there is some class method involved) – Frederick Cheung Apr 05 '13 at 11:48
  • @FrederickCheung I've tried it via `MyController.any_instance.should_receieve(:spawn_block)` - this is what gives the first error I showed, the second one is when I do it via class itself.. Is it possible that it doesn't work with "any_instance", but I can get it to work with the specific one (I am not sure how I an obtain it) – Yo Ludke Apr 05 '13 at 14:02
  • @controller is the controller instance used in a controller spec. You need the and_yield or else the block will not run – Frederick Cheung Apr 05 '13 at 15:17
  • It is okay for me that the block doesn't run.. I just want to spec that "something" happens, so I want to assert that `spawn_block` is called.. However with (I used `@controller.should_receive(:spawn_block).and_yield("sd")`) or without `.and_yield` it tells me that it didn't receive `spawn_block` – Yo Ludke Apr 08 '13 at 06:43
  • Are you sure that spawn_block is being called? – Frederick Cheung Apr 08 '13 at 06:58
  • @FrederickCheung I updated the question to give more details. In the console output when I run the test with rspec it tells me "spawn> parent PID = 5060 spawn> child PID = 5064 spawn> child[5064] took 0.001086 sec".. so yes, it is called and the spec results in ` @controller.should_receive(:spawn_block).and_yield("sd") (#).spawn_block(any args) expected: 1 time received: 0 times` – Yo Ludke Apr 08 '13 at 07:02

1 Answers1

1

You need to setup the expectation (the call to should_receive) before the code under test runs.

Frederick Cheung
  • 83,189
  • 8
  • 152
  • 174