I’ll just follow that up briefly to address your question of code smell. I
would not use any_instance here. The reason being is that you want to test
that this method does what you expect. While you are testing a class
method, new is a method on that class object. This means you are stubbing
the object under test. That is *always* (to me) a *huge* code smell.

In a nutshell, stubbing the object under tests makes your test essentially
useless. I could incorrectly change the implementation of that method and
your test will still happily pass. That’s not something you ever want.

If you are concerned about duplicating specs, I suggest taking a look at
shared_examples
<https://www.relishapp.com/rspec/rspec-core/docs/example-groups/shared-examples>
which would allow you to bundle tests of say “does some general group of
stuff when created with a vendor”. Then you could use them when testing
that method and when testing create separately.
​

On Thu, May 28, 2015 at 12:47 PM, Aaron Kromer <[email protected]>
wrote:

> It really depends on the objects. If that were PORO code I would pass in
> mocks for epoch and vendor. I would set my expectations of command
> methods on epoch and vendor accordingly as tests that the proper things
> are done. I would also check the public state of the returned object to
> ensure it was what I expected.
>
> Now I’m guessing by the naming this is ActiveRecord related. In that case,
> if epoch and vendor are other AR objects, I would likely let this method
> hit the database. I would then set my expectations on the public API of the
> returned object (as above), I would also check the state in the database,
> and the state of the collaborators if applicable.
>
> Now, when using this method, in say a controller spec, I would allow
> myself to stub it out (since it is *your* API): allow(ThatObjectClass).to
> receive(:create_from_vendor).and_return(this_mock_or_built_model).
> ​
>
> On Thu, May 28, 2015 at 11:43 AM, Marlin Pierce <[email protected]>
> wrote:
>
>> I saw the official discouragement of using expect_any_instance_of
>> and allow_any_instance_of on the page:
>>
>>
>> https://relishapp.com/rspec/rspec-mocks/docs/working-with-legacy-code/any-instance
>>
>> So, what should I do when I have a method which calls new to get a new
>> object of a class,
>> and then calls a method on that new object?  I want to stub the method
>> call,
>> because it does some complicated things which external resources,
>> and I want to have an expectation that the method is called.
>>
>>   def self.create_from_vendor(epoch, vendor)
>>     new(vendor).create(epoch)
>>   end
>>
>> Is there a way I need to rewrite my code to test this better?
>> Is this a smell?
>>
>>  --
>> 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/60034cee-8d5d-4053-ba10-1816a6c4ef03%40googlegroups.com
>> <https://groups.google.com/d/msgid/rspec/60034cee-8d5d-4053-ba10-1816a6c4ef03%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/CAKCESdgeiny3j2vY6bYSB8ddfdWBobFH%3Dt77q6fsj1k5rJK6dQ%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to