Hi Herby. 2017-10-20 18:49 GMT+02:00 Herby Vojčík <[email protected]>: > > > 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 the arguments of block in message #will: are expected to be arguments of stubbing message (not a full message instance). We can introduce new kind of expected action to automatically stub any result of message send: Foo stub new willStubRealResult. With help of new subclass of MockExpectedOriginalMethodCall: MockExpectedMethodResultStub>>executeFor: anOccurredMessage realMethodResult := super executeFor: anOccurredMessage. realMethodResult stub. ^realMethodResult. MockExpectedMessage>>willStubRealResult self will: MockExpectedMethodResultStub new And then you will be able specify expectations for all Foo instances: (Instance of: Foo) stub someMessage willReturn: #const And you will be able assert any message which was sent to Foo instances: (Instance of: Foo) should receive someRequiredMessage which should equal: #expectedValue I committed this code to the dev branch. But I am wondering that such kind of behaviour is really needed. Probably it is useful as you ask about it. > >> 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 >> >> >> >> >> > >
