Make it possible to serialize and deserialize a stub object. #81

Open
wants to merge 1 commit into
from

1 participant

@floehopper
Go Free Range member

Previously this was raising an exception because Mock#respond_to? was
being called before the instance of Mock has been re-hydrated i.e. none
of its instance variables had been set :-

NoMethodError: undefined method `matches_method?' for nil:NilClass

from gems/mocha-0.10.5/lib/mocha/mock.rb:185:in `respond_to?'

Note that I would not recommend using stubs in this way, but I decided
it was a shame that an exception was raised unnecessarily.

Note also that any expectations set on the original instance of Mock
will not be satisfied by invoking method on the re-hydrated instance of
Mock, because the two instances are completely different. This might be
solved by de-registering the Mock object when an instance with the same
"identitifer" is registered, but then I start wondering whether the
whole thing is a silly idea and we'd be better off raising an exception
if anyone attempts to serialize an instance of Mock.

@floehopper floehopper Make it possible to serialize and deserialize a stub object.
Previously this was raising an exception because Mock#respond_to? was
being called before the instance of Mock has been re-hydrated i.e. none
of its instance variables had been set :-

    NoMethodError: undefined method `matches_method?' for nil:NilClass
from gems/mocha-0.10.5/lib/mocha/mock.rb:185:in `respond_to?'

Note that I would not recommend using stubs in this way, but I decided
it was a shame that an exception was raised unnecessarily.

Note also that any expectations set on the original instance of Mock
will not be satisfied by invoking method on the re-hydrated instance of
Mock, because the two instances are completely different. This might be
solved by de-registering the Mock object when an instance with the same
"identitifer" is registered, but then I start wondering whether the
whole thing is a silly idea and we'd be better off raising an exception
if anyone attempts to serialize an instance of Mock.
d056986
@floehopper
Go Free Range member

See below for further info from Patrick who first reported the problem.

It would be good to understand whether or not there is a genuine need to do this.

Well... So I have a purchase model that integrates with a 3rd party
payment service. The model has a before_create callback which
contacts the 3rd party service and gets a transaction object from
them, this object is serialized and stored in the model. This
transaction object responds to methods "success?" and "capture"...
So, I have some state_machine stuff in the purchase model that does
various things IF that object is success? and if capture returns true
etc.. So when I was writing specs, I obviously don't really want to
be hitting the API of the 3rd party service, so I stubbed that out and
wanted it to just return a fake transaction object that has success
and capture methods that I could make true/false depending on what I
was testing. So that's why... I am open to alternative approaches/
ideas if you have any.

BTW, my current workaround was to simply do in my test's before block:

30 Purchase.class_eval do
31 attr_accessor :txn
32 end

That way, it skips storing it in the db, and I didn't really need to
test anything to do with retrieving that object.

@floehopper
Go Free Range member

Even though I wrote it, I'm not at all convinced this pull request should be merged as it stands. As per the commit message it might be better to fail fast and raise an exception if any attempt is made to serialize a mock/stub.

@floehopper
Go Free Range member

While it does seem possible to prevent serializing to YAML with the syck engine by overriding #to_yaml and raising a TypeError. This solution does not work for the newer pysch engine. I've asked the psych people for help - tenderlove/psych#112.

Note: we should also do something similar for Marshal i.e. define #marshal_load to raise a TypeError.

@floehopper
Go Free Range member

There is now a way to make the psych engine fail-fast - see tenderlove/psych#112.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment