Re: [Pyobjc-dev] TypeError: cannot change a method
Brought to you by:
ronaldoussoren
From: Daniel M. <mil...@gm...> - 2009-07-17 01:12:42
|
RESENDING -- inadvertently sent this directly to Ronald > Could you post some code that shows what you're trying to do? # test something involving NSDocument.removeWindowContorller_ doc = MyNSDocumentSubclass.alloc().init() original = doc.removeWindowController_ fake = mocker.mock() doc.removeWindowController_ = fake try: fake(arg) # simulate call (record expectation) ... # replay ... # our fake method is called by the routine we are testing doc.removeWindowController_(arg) ... finally: doc.removeWindowController_ = original ... # verify that simulated calls actually happened assert was_called(fake) This is obviously only pseudo code. My framework makes it much more convenient to mock one or more methods and then replace them during the verify phase. > I haven't checked the source code yet, but one reason to be careful > about overwriting methods in Cocoa classes is that will affect the > actual Cocoa class as wel. > > Footnote [0] refers to replacing a method in an instance by > something else, e.g.: > > o = NSObject.alloc().init() > o.description = 42 Yeah, that's what I'm doing. > That's not allowed because this can lead to very hard to diagnose > bugs, and the people that are most likely to run into those are > people new to PyObjC that translate existing ObjC sample code into > Python (the reason of that is that ObjC has different namespaces for > methods and instance variables, while Python has only a single > namespace for both of them). I'm not quite sure what to say other than I'll need to look into rewriting my test framework. FWIW, it seems to be possible to replace a method directly on the PyObjC type. For example: # this works fake = descriptor_mock() NSDocument.removeWindowController_ = fake Assuming the 'fake' object implements the descriptor protocol, the fake/mocked method will get called as expected. But it then it fails when trying to restore the original method: NSDocument.removeWindowController_ = original # TypeError: Assigning native selectors is not supported However, this seems to restore the original: del NSDocument.removeWindowController_ Strange... while I may be able to use this approach, it has the disadvantage of replacing the method on ALL instances of the type rather than on just a the instance that I'm testing--I may need to rewrite some tests to work with that restriction, but it probably wouldn't be the end of the world. ~ Daniel |