Mocking the initialize method on a ruby class?
How can I mock the initialize method on a ruby class?
I'm doing some testing and want to mock out the object that is created from 开发者_如何转开发a new call.
I tried to write a few things and none of them seemed to get the mock class to return from the new call. It just keeps returning the normal, expected object.
EDIT:
one attempt -
class MockReminderTimingInfoParser < ReminderTimingInfoParser
def new(blank)
ReminderTimingInfoParserForTest.new
end
end
describe ReminderParser do
parser = ReminderParser.new(MockReminderTimingInfoParser)
it "should parse line into a Reminder" do
parser.parse(" doesnt matter \"message\"").should == Reminder.new('message', ReminderTimingInfo.new([DaysOfWeek.new([:sundays])], [1]))
end
end
class ReminderTimingInfoParserForTest
include TimingInfoParser
def parse_section(section); [DaysOfWeek.new([:sundays]), 1] end
def reminder_times_converter(times); times end
end
class MockReminderTimingInfoParser < ReminderTimingInfoParser
def new(blank)
ReminderTimingInfoParserForTest.new
end
end
Here, you are defining a method called new
for all instances of the class MockReminderTimingInfoParser
. In your question, you mention that you want to hook into instance creation. However, in Ruby, instance creation is not done by instance methods. Obviously, this cannot work, since in order to call an instance method, you'd need to have an instance first!
Instead, instances are created by calling a factory method (commonly called new
) on the class.
In other words, in order to create an instance of MockReminderTimingInfoParser
, you would call MockReminderTimingInfoParser.new
, but you have defined a method MockReminderTimingInfoParser#new
. In order to call the method you have defined, you would have to call MockReminderTimingInfoParser.new.new
.
You need to define a method on MockReminderTimingInfoParser
's singleton class. There's several ways to do that. One way would be just mimicking the way you would call the method:
def MockReminderTimingInfoParser.new(blank)
ReminderTimingInfoParserForTest.new
end
Another would be opening up MockReminderTimingInfoParser
's singleton class:
class << MockReminderTimingInfoParser
def new(blank)
ReminderTimingInfoParserForTest.new
end
end
However, in both of these cases, MockReminderTimingInfoParser
obviously has to exist first. Given that you need to define the class anyway, here's the most idiomatic way of defining methods on a class's (or module's) singleton class:
class MockReminderTimingInfoParser < ReminderTimingInfoParser
def self.new(blank)
ReminderTimingInfoParserForTest.new
end
end
Could you inherit the class and then supply your own initialize?
精彩评论