Chris R. wrote:
Are you able to expand upon your actual requirements? I’ve just been
speaking to James (mocha author) and we’re pretty certain we can help
but would like a little more clarification.
Hi Chris,
Apologies for the delayed reply - I use ruby-forum.com to keep up with
this list, and it seems to have been a bit “wobbly” recently 
Rather than concoct another example, I’ll give you a simplified version
of our actual code. Our system sends and receives (SMS) messages. We
have a Conversation model class which represents a set of incoming and
outgoing messages. One of the methods on Conversation is
“send_unsolicited” which creates a Conversation containing a single
outgoing message and then sends the message. The code goes something
like this:
class Conversation
class << self
def send_unsolicited(customer, message)
c = create_unsolicited(customer, message)
c.send_now!
c.unlock!
return c
end
def create_unsolicited(customer, message)
c = Conversation.create :customer => customer, :locked_by_user_id
=> 1
m = c.create_in_progress_outgoing_message :body => message
return c
end
end
def unlock!
self.locked_by_user = nil
save!
end
def create_in_progress_outgoing_message(options = {})
# …
end
def send_now!
# …
end
end
We have a test in which, among other things, we want to verify that
send_unsolicited unlocks the conversation. It’s not enough for us to
verify that the conversation isn’t locked when it returns - we need to
be certain that it’s actually called the unlock! method.
At the moment the test is as follows:
module HookCreate
def new(options = {})
c = super options
c.extend HookUnlock
return c
end
end
module HookUnlock
attr_reader :was_unlocked
def unlock!
super
@was_unlocked = true
end
end
def test_send_unsolicited
Conversation.extend HookCreate
c = Conversation.send_unsolicited customers(:customer1), “Blah blah
blah”
assert c.was_unlocked
end
Which works, but is nasty. And doesn’t scale well if more than one test
needs to do the same thing.
Make sense?
Ideally, we would like some way to say “in the test environment,
whenever you create a Conversation class, instrument it as follows”. The
test/mocks directory gives us a convenient way of saying “in the test
environment, whenever you create a Conversation class, create this mock
class instead”, but that’s not quite what we want 
If a mock could extend the class that it’s pretending to be instead of
simply replacing it, that would be perfect. But I’m not aware of any way
to achieve this in Rails as things stand.
Thanks in advance for your help!
paul.butcher->msgCount++