Use msw to test http-client requests #190
Closed
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
TL;DR I'm using
msw
to write tests, but I'm usingmsw
weirdly, but I have good reasons.Draft Phrase Preamble
Before I dive in and write ~20 tests using this approach, I want to get some soft consensus that people like testing the http-client this way. I tried several different libraries for mocking
fetch
and testingfetch
requests, and honestly don't like any of them, but I've settled on an approach that works for our use case.Overview
Our current tests in the http-client are brittle. We test that we can call methods like
TbdexHttpClient.sendMessage
to make sure that they do notthrow
, but we have no assertions that we are actually sending a message to the correct url with the correct request structure. The aim of this PR is to add those tests.We select
msw
to accomplish this becausemsw
has allows us to record requests to an endpoint andmsw
supports a wider variety of environments that other libraries.Testing libraries comparison
I'll start by saying I settled on
msw
, but deliberately going against some of its recommended best practices. More detail below.nock
I found nock the most ergonomic for setting up one-time request interceptors. Its API was exactly what I wanted. Sadly it has limited environment support, and I don't want to have to re-write all these tests again in a month when nock inevitably doesn't cut it.
Polly.js
I had high hopes when I saw Netflix built it, but the docs are all over the place and it's pretty complex to set up. The quickstart is broken and uses deprecated APIs, and finally saw that the adapter I needed was built on top of
nock
anyway.msw
Rant: I tried
msw
first, hated it, then came crawling back. I don't like thatmsw
feels like reimplementing the server in the test files. I REALLY don't like having a separatehandlers.js
where all the defaultmocksrequest handlers go. Kent C Dodds seems to love how short it makes his tests, but personally I find it hard to read what the test is actually testing for.To better accommodate
my neurosesour use case, these tests deliberately go against some of MSW's officially recommended best practices. In particular, these tests make request assertions . MSW's reasoning is that request assertions tend to test implementation rather than behavior. This makes sense for apps where one entity controls (and can freely make changes to) both the client and server. However, we are implementing a spec, and must be sure that our client adheres precisely to the spec in the requests' url, header, and body.Though other libraries (e.g. nock) supply assertions for request url, header, and body matching out of the box, we choose MSW because it has support for a wide variety of environments. To adapt it for our use case, we make extensive use of
server.use(http.get({ once: true, ... }))
as a form of assertion.