Skip to content

Commit 307aa79

Browse files
committed
start on a new blog post
1 parent 59e9492 commit 307aa79

3 files changed

Lines changed: 119 additions & 0 deletions

File tree

_config.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,4 @@ favicons: # Favicons are also used in the manifest file. Syntax is 'size: path'
1919
navigation_header:
2020
- title: Home
2121
url: /
22+
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
---
2+
title: Testing external API calls
3+
layout: post
4+
author: Harry
5+
categories:
6+
- testing
7+
tags:
8+
- tdd
9+
- fakes
10+
- mocks
11+
- adapters
12+
---
13+
14+
## Notes
15+
16+
common question, how do i write tests for external api calls
17+
18+
example tbc
19+
20+
common solution. use mocks and mock.patch. fine, actually, if you
21+
have just one call to one endpoint
22+
23+
pros:
24+
* no change to client code
25+
* low effort
26+
* everyone understands it
27+
28+
cons:
29+
* tightly coupled
30+
* brittle. requests.get -> requests.Session().get will break it.
31+
* need to remember to `@mock.patch` every single test that might
32+
end up invoking that api
33+
34+
35+
- could mention vcr.py here. ingenious but i've found it confuses ppl.
36+
37+
* and you still need an integration test or two, and maybe an E2E test.
38+
so you need a sandbox, or some way of faking it out irl
39+
40+
link to ed "mocking pitfalls" video
41+
42+
43+
# step 1: DI
44+
45+
example
46+
47+
- this will fix your brittleness and "remember to mock.patch" problem
48+
- comes at the cost of a new "unnecessary" argument to your app code
49+
* some people like that tho.
50+
51+
52+
link to brandon "hoist your io" video
53+
54+
55+
# step 2a: build an adapter. or a wrapper. or whatever you want to call it
56+
57+
- maybe not worth it if you really do only have that one api call
58+
59+
but if there's more, this is great.
60+
61+
example goes here
62+
63+
64+
65+
66+
# step 2b: integration tests for the adapter
67+
68+
* mention contract testing
69+
* you still need to solve the sandbox problem here
70+
71+
72+
# step 2c: unit tests for the things that use the adapter
73+
74+
* test pyramid yay
75+
76+
77+
# step 2d: consider building a fake for CI
78+
79+
* once you've got an integration working, if it's not the core
80+
of you're app, you don't your CI builds to be flakey because
81+
a third party is flakey
82+
83+
84+
85+
example here
86+
87+
pros: faster CI, faster local dev
88+
cons: need a way to occasionally run tests against the real thing.
89+
also: more code
90+
91+
92+
# general pros + cons re: adapters
93+
94+
pros:
95+
* no brittle mocks everywhere
96+
* decoupling; our app code is now no longer dependeent on the specific api
97+
we're calling. if it changes, or we change it, our app doesnt need to know
98+
* and our app code looks nicer too
99+
* we've created a clear separation between things that get unit tested
100+
and things that get integration tested
101+
102+
cons:
103+
* more code
104+
* DI is still a hard sell in the python world
105+
106+

index.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,18 @@ _(Because "Cosmos" is the [opposite of Chaos](https://www.goodreads.com/quotes/6
2525

2626
## Blog
2727

28+
### Recent posts
29+
30+
<ul>
31+
{% for post in site.posts reversed %}
32+
{% assign year = post.date | date: "%Y" %}
33+
{% if year != "2017" %}
34+
<li>
35+
<a href="{{ post.url }}">{{ post.date | date: "%Y-%m-%d" }} {{ post.title }}</a>
36+
</li>
37+
{% endif %}
38+
{% endfor %}
39+
</ul>
2840

2941
### Classic 2017 Episodes on Ports & Adapters, by Bob
3042

0 commit comments

Comments
 (0)