Mock Objects

Torsten Bergmann astares at gmx.de
Tue Jun 27 21:27:22 UTC 2006


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 




More information about the Squeak-dev mailing list