From: Robert Klemme Date: 2005-03-15T23:01:21+09:00 Subject: Re: Mocking new and other class methods "jeem" schrieb im Newsbeitrag news:1110831120.593168.314560@o13g2000cwo.googlegroups.com... > Hello group. I wanted to be able to do something like this: > > def testItResizesTheImage > imageNew=ClassMethodMocker.new(Magick::Image,:new) > image=FlexMock.new > imageNew.handle { |imagePath| assert_equal(@imagePath,imagePage); > image } > image.mock_handle(:somecall) { |etc| etc } > # etc > test_subj.doThatThing > image.mock_verify > imageNew.verify > end > > So, I wrote a few loc to enable it (borrowing from FlexMock) for 'new' > calls at least. I'm having second thoughts about how I implemented it, > so I was hoping some in the ng might want to kick it around. > > My big concern with the current method (see below) is that the real new > might not be "put back" if a coder doesn't use MockNew.use. Blocks with ensure could help here as transactional context. > I have other ways in mind to allow mocking of class methods, but they > all seem to put up new hoops for coders to jump through, and make the > resulting code less natural. Sorry, I'm not really sure what you're after. What I extracted from your code is that you iterate through a set of new methods and use the original one in the end. IMHO you can get that with much less effort and less meta programming: class MockClass def initialize(cl, *handlers) @cl = cl @handlers = handlers @idx = 0 end def new(*a) h = @handlers[@idx] if h @idx += 1 h.call(*a) else @cl.new(*a) end end end cl_fake = MockClass.new(String, lambda {|*a| "1"}, lambda {|*a| "2"} ) >> cl_fake.new "a" => "1" >> cl_fake.new "a" => "2" >> cl_fake.new "a" => "a" >> cl_fake.new "a" => "a" >> cl_fake.new "a" => "a" Kind regards robert