开发者

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?

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜