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 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 |
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 > 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: '{}') ] ]). Actually, cleaned it up a bit, now I use shorter: ZnClient stub new will: [ ZnMockClient whenRequest: [ :request | request uri = ('https://onesignal.com/api/v1/players/{1}?app_id={2}' format: { UUID fromString36: 'Q7'. appId }) asZnUrl 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 > |
Free forum by Nabble | Edit this page |