On Tuesday, July 15, 2014 1:53:16 PM UTC-7, Elad Ossadon wrote:
>
> In the following case I don't have access to created_object until it's 
> created, but I expect that somewhere inside SomeCreateService.create the 
> method SomeProcessService.create would be called with the created object:
>
>
> it "does something" do
>   expect(SomeProcessService).to receive(:process) do |object|
>     expect(object).to eq(created_object)
>   end
>
>   created_object = SomeCreateService.create!
> end
>
>
> This works, though:
>
>
> it "does something" do
>   called_with_object = nil
>   expect(SomeProcessService).to receive(:process) do |object|
>     called_with_object = object
>   end
>
>   created_object = SomeCreateService.create!
>   expect(created_object).to eq(called_with_object)
> end
>
>
> Is there a nicer way? (Like delaying all the receive expectations to the 
> end of the example)
>

This is simply how closures work: it retains access to local variables that 
exist when the closure is defined, but not to local variables that are 
created later on.

Two simple solutions:

* Use an instance variable rather than a local variable for 
`created_object`.  This does not rely on the semantics of the closure and 
instead will rely on the value of `self` (which will be the same in both 
scopes).
* Treat `SomeProcessService` as a spy and use `expect(SomeProessService).to 
have_received` at the end of your example.  Our docs [1] have more 
information on spies.

HTH,
Myron

[1] https://relishapp.com/rspec/rspec-mocks/v/3-0/docs/basics/spies

-- 
You received this message because you are subscribed to the Google Groups 
"rspec" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/rspec/55e04cad-6ce6-4deb-a836-2ef33b11d3af%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to