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