Mock Objects

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

Mock Objects

Torsten Bergmann
Hi Chad,>I find I am using mocks as a type of scaffolding which helps me

>explore the behaviors I'll need to implement in the classes I'm
>mocking.  Once I acually create the real class (or a mock class of the
>real class), I'll likely replace my on-the-fly mocks with them.Would be a
>nice experiment to teach an object and to see howmuch of the teached
>behavior could be used to generate/create the mock class automatically.
>Think of an "auto-implementation" framework where you tell the objects how
>to react in different situtions and smalltalk implementsitself. This is at
>least possible for simple stuff:   anObject     whenSend: #foo:
>withArgument: 1                 respondWith: true
>inAnyOtherCaseRespondWith: false.may result in semi-autoimplemented code:
>foo: anObject     ^anObject = 1 ifTrue:  [true]                   ifFalse:
>[false]So you can write simple scenarios in plain Smalltalk and get helpfor
>the implementation phase. One general problem you may run into if you use
>mocks is thatthe tested code may check for the class of an object.
>Sometimes codelooks like this:   "anObject class == Number ifTrue:
>[doSomething]"There is a Smallint rule finding "such code" smells. Better
>code uses    "anObject isNumber ifTrue: [doSomething]"But it is also not
>wise to have thousands of "isClassName" methods,so typically "anObject
>isKindOf: " or "anObject isMemberOf:" is used.If we really want to create
>an identical mock object we need something like:  |foo|  foo := Teachable
>new.  foo whenSend: #class return: Object.  foo class inspectSince #class
>is already implemented in Object the DNU trick will not work.We could
>implement the following method in Teachable on the instance side:class    |
>learning |  Transcript show: 'called'.  learning := self learnings      at:
>#class     ifAbsent:[].  ^learning class == Association          ifTrue:
>[learning value]        ifFalse: [super class]Unfortunately Squeak
>optimizes the call to #class into a special bytecode(16rC7 which is
>bytecodePrimClass) - so our own class method never gets called. Therefore
>"foo class inspect" will still return the Teachable class! If you step
>through the code in the Debugger using "foo halt class inspect" the call to
>#class it is not optimized and works as expected.Unfortunately solving this
>problem means changing the Compiler to prevent the #class optimization on
>Teachable instances...ByeTorsten