Just to throw this out there, but it seems this spec has helped identify a
sticky point in your current design. Perhaps dependency injection would be
helpful here.
You could easily inject an
instance_double("SomeProcessService").as_null_object. If necessary, you
could also create a new fake class that does something more complex. That
would allow other more invasive verifications without worrying about the
actual process service internals.
On Tue, Jul 15, 2014 at 5:40 PM, Elad Ossadon <[email protected]> wrote:
> have_received! Exactly what I was looking for. Thanks.
>
> it "does something" do
> allow(SomeProcessService).to receive(:process)
> created_object = SomeCreateService.create!
> expect(SomeProcessService).to have_received(:process).with(
> created_object)
> end
>
>
>
> On Tuesday, July 15, 2014 2:02:03 PM UTC-7, Myron Marston wrote:
>>
>>
>>
>> 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/02c0f8d7-85e6-4ef0-b7c2-0d90c09ce413%40googlegroups.com
> <https://groups.google.com/d/msgid/rspec/02c0f8d7-85e6-4ef0-b7c2-0d90c09ce413%40googlegroups.com?utm_medium=email&utm_source=footer>
> .
> For more options, visit https://groups.google.com/d/optout.
>
--
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/CAKCESdihU6GDapsygLrysX%2By8NsbDt%2BcvZxTjy%3DpqbMSiCsCEQ%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.