Denis Kudriashov wrote:
So you want to stub message to *any* instance of class. Right?

Conceptually, in Mocketry/StateSpecs way, it should looks like:

    (Instance of: Something) stub askForName willReturn: 'new'.

    or:

    (Kind of: Something) stub askForName willReturn: 'new'.


But it will not really works. It will work only on instances which are
already "stubbed".
Making it really transparent will require crazy magic underhood. And I
am not sure that it is really possible.
Because generally it should cover existing instances and not just newly
created during test.
And for simple case: to automatically stub new instances their classes
should be stubbed with special constructors. But system do not know what
exact class side messages are constructors.

I had this problem. I tried something like (though not exactly w/ this code):

Foo stub new will: [ :aMessage |
  | original |
  original := MockExpectedOriginalCall new executeFor: aMessage.
  original stub.
  ^ original ]

but IIRC it failed on doing #stub inside will: block.


So now you can just use simple mock which will be returned as simple
stub from concrete constructor of your class:

    some := Mock new.

    some stub askForName: 'new'.

    Something stub new willReturn: some.


I think it looks not not bad and no crazy magic is evolved. And of
course you can replace mock with real instance if you want:

    some := Something new.

    some stub askForName: 'new'.

    Something stub new willReturn: some.



2017-10-20 14:21 GMT+02:00 Denis Kudriashov <[email protected]
<mailto:[email protected]>>:

    Yes, but in that case you stub messages to the class itself. For
    your example it means:

        Something stub askForName willReturn: 'new'.

    Something askForName should be: 'new'



    2017-10-20 13:58 GMT+02:00 Peter Uhnák <[email protected]
    <mailto:[email protected]>>:

        Thanks Denis, that did the trick.

        But I thought that I can also mock at the class level (at least
        it was shown in the docs).

        Peter

        On Sat, Oct 7, 2017 at 11:24 AM, Denis Kudriashov
        <[email protected] <mailto:[email protected]>> wrote:

            Hi Peter.

            You should stub instance instead of class:
                  s := Something new.
                  s stub askFor...

            7 окт. 2017 г. 9:18 пользователь "Peter Uhnák"
            <[email protected] <mailto:[email protected]>> написал:

                Hi,

                maybe I am missing something fundamental, because this
                seems like an obvious scenario

                I have a class Something with two methods

                Something>>askForName
                ^ UIManager default request: 'Name'

                Something>>name
                ^ self askForName , ' suffix'

                Now I want to mock out askForName, so I can run it
                automatically in tests...

                I've tried just stubbing it...

                SomethingTest>>testRenameStub
                Something stub askForName willReturn: 'new'.
                Something new name should be: 'new suffix'

                however it still opens the window to ask for the name,
                so the original method is being called.

                Right now I have to stub it with metalinks, which
                doesn't play well with some tools (hapao)

                SomethingTest>>testRenameMeta
                | link newName |
                link := MetaLink new
                metaObject: [ 'new' ];
                control: #instead.
                (Something >> #askForName) ast link: link.
                [ newName := Something new name ]
                ensure: [ link uninstall ].
                self assert: newName equals: 'new suffix'

                Thanks,
                Peter






Reply via email to