Hi Herby.

There is message #will: which accepts the block with possible arguments (if
needed).

 ZnClient stub new will: [ ZnMockClient ...]

But generally your approach looks bad to me. You put too many details on
your tests which just duplicate Zinc API used in the domain code. It makes
tests brittle and tightly coupled. And they looks quite unreadable.

I usually introduce kind of MyExternalClient intermediate which provides
normal messages to interact with remote system.  And it completely hides
overall http communication.
So in tests I stub this guy with simple mocks.
But in addition I write real communication tests specifically for that
object. They can be unstable because it is real network. But idea to test
actual communication in single place and abstract the rest of system from
it. Also it provide good checker for the possible API changes and general
problems with service.

Best regards,
Denis


2017-10-17 12:34 GMT+02:00 Herby Vojčík <he...@mailbox.sk>:

> Herby Vojčík wrote:
>
>> Hello!
>>
>> I felt the need to mock http api (like nock in node, that is, mock http
>> request-response itself on low-level part, leaving aside the question of
>> what wrapper / library one uses to get to that http; in node it mocks
>> basic http layer, here I tackled ZnClient), but struggled for a time how
>> to grasp it. Finally I used something like this (with help of Mocketry,
>> `1 to: 10` to mean "enough to actually be used even if there are more
>> unrelated uses", it could as well be `1 to: 100`):
>>
>> ZnClient stub new willReturnValueFrom:
>> ((1 to: 10) collect: [ :i | ZnMockClient
>>
>
> For Denis Kudriashov: would you be willing to add something like
> `willGenerateValueFrom: aBlock` to Mocketry, so previous two lines could be
> replaced by simpler:
>
>   ZnClient stub new willGenerateValueFrom: [ ZnMockClient
>
> ?
>
> If something allowing it is there, I am sorry but I haven't found it.
>
> Herby
>
> whenRequest: [ :request |
>> { request uri scheme. request uri authority. request uri
>> pathPrintString. request uri query associations asSet }
>> = { #https. 'onesignal.com'. '/api/v1/players/{1}' format: { UUID
>> fromString36: 'Q7' }. { 'app_id' -> appId } asSet }
>> and: [ #(GET HEAD) includes: request method ] ]
>> thenResponse: [ :request | ZnResponse ok: (ZnEntity json: '{}') ] ]).
>>
>> with the help of this class (garbled utf not my fault, iceberg metacello
>> integration does it):
>>
>> 'From Pharo6.0 of 13 May 2016 [Latest update: #60512] on 17 October 2017
>> at 12:05:38.908634 pm'!
>> ZnClient subclass: #ZnMockClient
>> instanceVariableNames: 'conditionBlock responseBlock'
>> classVariableNames: ''
>> poolDictionaries: ''
>> category: 'Towergame-Tests'!
>> !ZnMockClient commentStamp: 'HerbyVojcik 10/16/2017 16:43' prior: 0!
>> I am a mock ZnClient.
>>
>> I am created with ZnMockClient whenRequest: whenBlock thenResponse:
>> thenBlock.
>>
>> Upon execution of the request, when (whenBlock cull: request) is true,
>> response is set to (thenBlock cull: request). Otherwise, behaviour is
>> delegated to super.!
>>
>>
>> !ZnMockClient methodsFor: 'accessing' stamp: 'HerbertVojÄ Ã­k 10/17/2017
>> 12:00:27'!
>> conditionBlock
>> ^ conditionBlock! !
>>
>> !ZnMockClient methodsFor: 'accessing' stamp: 'HerbertVojÄ Ã­k 10/17/2017
>> 12:00:27'!
>> responseBlock: anObject
>> responseBlock := anObject! !
>>
>> !ZnMockClient methodsFor: 'accessing' stamp: 'HerbertVojÄ Ã­k 10/17/2017
>> 12:00:27'!
>> conditionBlock: anObject
>> conditionBlock := anObject! !
>>
>> !ZnMockClient methodsFor: 'accessing' stamp: 'HerbertVojÄ Ã­k 10/17/2017
>> 12:00:27'!
>> responseBlock
>> ^ responseBlock! !
>>
>>
>> !ZnMockClient methodsFor: 'private protocol' stamp: 'HerbertVojÄ Ã­k
>> 10/17/2017 12:00:27'!
>> executeRequestResponse
>> ^ (self conditionBlock cull: self request)
>> ifTrue: [ response := self responseBlock cull: self request. response
>> contents ]
>> ifFalse: [ super executeRequestResponse ]! !
>>
>> "-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!
>>
>> ZnMockClient class
>> instanceVariableNames: ''!
>>
>> !ZnMockClient class methodsFor: 'instance creation' stamp:
>> 'HerbertVojÄ Ã­k 10/17/2017 12:00:27'!
>> whenRequest: aBlock thenResponse: anotherBlock
>> ^ self new
>> conditionBlock: aBlock;
>> responseBlock: anotherBlock;
>> yourself! !
>>
>> Question 1: Is there a better way?
>>
>> Question 2: If not, would ZnMockClient be good addition to Zinc itself,
>> to ease testing for others?
>>
>> Herby
>>
>>
>

Reply via email to