
MirageJS: An API mocking library for frontend development - mixonic
https://miragejs.com/
======
samselikoff
Hello! I'm Sam and I built Mirage JS to be a framework-agnostic API mocking
library.

Mirage is extracted it from an addon that's been widely used in the Ember
ecosystem for the past 4 years, at companies like Apple, Heroku, Square and
Footlocker.

Nearly all frontends need to talk to an API, no matter what framework they're
built with! So over the past year I've made Mirage work with any tool or test
runner.

I really believe deeply in the frontend-first workflow, and Mirage makes that
easier than ever. If it sounds interesting to you, check out the lib + let me
know what you think!

~~~
ketzo
Phenomenal landing page. The first text I read is a ~10-word description of
the value proposition. The next thing my eyes are drawn to is a visual demo.
The first thing I can click is a link to use it myself. Plus, it's all
visually very appealing without being distracting. Well done.

~~~
samselikoff
We spent a long time on it so that really means a lot! Thanks for the kind
words :)

------
hinkley
I believe Michael Feathers was just started a Twitter thread yesterday that
talked, among other things, about moving IO to the edges of your code.

If you can divide acquisition from usage, I wonder how much less effort you
need to put into API mocking.

Ages ago and shortly after I started testing, was the last time I had to do
any low-level HTTP response processing. My coworkers could not fathom why I
had divided the parsing and networking code into completely separate sections.
Then I showed them how stupid-simple most of the tests were, instead of the
convoluted mess of integration tests I'd walked into.

Hand the payload to I/O-free code immediately. You've done the hardest part at
this point. Mocking out the network layer in any of half a dozen ways is a
cakewalk in comparison.

~~~
adamkl
Yes! Yes! Yes! I've been preaching this approach ever since watching Gary
Bernhardt's talk on "Boundaries" [1].

Splitting conditional logic from dependencies makes code so much easier to
test. If you can do that, there's no need to mock anything. You can just pass
simple data objects into your conditional logic for testing, and use a handful
of integration tests to validate the end-to-end flow.

[1]
[https://www.destroyallsoftware.com/talks/boundaries](https://www.destroyallsoftware.com/talks/boundaries)

~~~
hinkley
Bertrand Meyer talked a similar strategy. I believe he called them decisions
and actions. There's a _lot_ of requirements tied up in decisions.

With the exception of callbacks (and async solves that for single-issue
scenarios), arguments don't need to be mocked. They're just arguments.

------
shhsshs
What is the benefit of a request mocking framework versus hiding all api
requests behind a module?

Instead of

    
    
        // MyComponent.js
        const users = await fetch(...
    

Use this

    
    
        // MyComponent.js
        const users = await api.getUsers()
    
        // api.js
        export default {
          getUsers() {
            return fetch(...
          }
        }
    

To mock, you replace the entire api module (or individual functions).

~~~
cbhl
The first page of the docs list a few reasons.

[https://miragejs.com/docs/getting-
started/introduction](https://miragejs.com/docs/getting-started/introduction)

"Use a client-side interceptor to handle your app's network requests. ... This
is the most flexible approach, but it requires you to start from scratch in
each project, and leaves it up to you to enforce conventions across your
apps."

"Importantly, because Mirage mocks the HTTP boundary instead of the JavaScript
code your app uses to make network requests, you never need to modify your
application code to account for whether your app is talking to Mirage or to
your real production backend."

~~~
rclayton
How is this the best/most flexible approach? What if you decide to move from
REST to GQL? GQL to websockets? By mocking the HTTP endpoint you’re too low in
the stack. At that point, I feel like you might have better success with using
the actual backend and swap out the DB with mock data.

~~~
KitDuncan
I always use this approach for my E2E tests. This way I test the backend as
well as the frontend. Harder to setup properly though.

------
rubyn00bie
Just my two cents: Mirage is freaking great because it makes mocking shit out
pretty much as easy as possible and pretty damn correct.

I don't know how many times mocking up a UI I start to throw some random JS
objects in a file and then inevitably after a few hours, those random JS
objects are unmanageable and contain very small differences between what my
API will deliver.

Using Mirage from the start of projects has made my life a lot easier, it also
provides a nice sanity check between what the backend delivers and what the
frontend actually expects.

~~~
ficklepickle
How does mirage help with data differences with the real back end? I can't see
how it isn't just as vulnerable to getting out of sync.

I have another question. Mirage is installed as a dev dependency. But all the
examples show it being used in the application code. Do you maintain a
separate branch without the import of Server, etc? Or is webpack smart enough
to remove all imports/usage of dev dependencies in the prod build? I don't
think I've ever imported dev dependencies into app code before.

For that matter, how does it provide a sanity check between what the back end
delivers and the front end expects? Do you mean compared to coding to a spec
with no mocking? Like when the back end doesn't exist yet?

Clearly I'm missing something. Could be the sleep deprivation.

~~~
samselikoff
Great question! When I started Mirage this was the biggest concern, but after
years of usage it turns out to not be that big of a deal in practice. Said
another way, the benefits of being able to easily write high-level UI tests
for a variety of server states all within your frontend codebase outweigh the
costs of potential false positives. Also, teams don't break their HTTP APIs
that often.

Even so, there are teams that have used tools like Pact to perform contract
testing, ensuring their Mirage server and their production API never fall out
of sync. Even more exciting to me would be using something like Typescript to
verify the API contract at compile-time (also something that others have been
exploring).

As far as only running Mirage during development, the Ember addon does this
but we need to document how to do this in the general case. When you build
your app for production Mirage should not be in any application code, nor
should the miragejs library be included in your bundle. Webpack is capable of
this, we just need to document it.

Mirage is flexible enough to match any backend API – this is where it shines
in comparison to tools like json-server. With Mirage the goal is to mock out
your exact production API; its serializers and route handlers can be
customized to match any API format. Often teams using Mirage reach agreement
about the shape of their API beforehand, precisely so that the frontend team
can move and build the UI without having to wait on the API to be ready.

Indeed, Mirage can even be thought of as a communication tool that helps
impose conventions and consistency on the API layer, making both the frontend
developers and the backend developers happier.

------
ravenstine
Mirage is a staple of Ember development. It's one of those things I didn't
realize I was missing until I learned it, and now I can't imagine not using
it(at least in early development). I kinda didn't realize I could use it
outside of Ember CLI, so this is pretty cool.

------
holler
I've used mirage extensively throughout the past 5+ years across multiple
projects/teams and it truly is a great tool. In a recent project we had
multiple "scenarios" defined that represented different high-level states of
the app. We added a page that allowed switching between the scenarios during
local development and it was a huge boon to productivity, while also allowing
us to write certain automated smoke tests that otherwise would have been more
cumbersome with e.g. selenium.

Working on a React project recently, I was surprised that there wasn't an
option like mirage, but now that there is, I highly recommend it!

------
zackify
I would rather make a component that takes data as props.

Now make a component on top that runs a network request and injects the
network response into it.

Now you have a reusable component independent of the api. Your network
function can be tested individually. Your top level component doesn’t need
testing as that is the part that would be mocked.

You can now test your actual component without any mocking.

If you need some dummy data to show before the backend team is ready, this is
trivial. Guess I’m just not a Big enough mocking fan to ever need a library
for what is such a small thing in my experience

~~~
virtue3
We use the "container" pattern for this via graphql (the container component
handles all the data fetching and logic therein, the underlying component is
usually attempted to be pure / functional / stateless. )

------
SaladFork
I used Mirage with Ember for many years and it has changed the way I think and
approach front-end acceptance testing. I was very excited to see the work to
extract the Ember-specific bits from the rest of the library (originally by
@cowboyd / Charles Lowell and now from the original author Sam Selikoff
himself) and am using it with a React app to great success.

------
sadlion
You beat me to this idea but I'm glad you did. Nice library. Mock API's are
quite the productivity multiplier. I use them extensively for local
development, prototyping, testing, and demoing. I've hacked similar things for
work; first one was based on jsondb and the second one was based on axios-
mock-adapter.

Colorizing[1] the console logs for quickly parsing success and failure might
be a nice addition. [1]: [https://developers.google.com/web/tools/chrome-
devtools/cons...](https://developers.google.com/web/tools/chrome-
devtools/console/console-write#styling_console_output_with_css)

edit: grammar

------
ibero
Been using the original Mirage project on an Ember app for years (testing and
fake offline demos functionality), and now this iteration takes it over the
top. I can't recommend it enough.

------
quaunaut
I remember using Mirage back when I was an Ember developer. Everything else
seemed so backwards in comparison, and honestly still does. I'm definitely
interested in trying this out.

------
hn_throwaway_99
This is cool. Mockability is one reason I've been so heavily biased to
choosing GraphQL for my backend APIs recently. GraphQL makes it super easy to
(a) first define a contract between client and server, and then (b) front end
teams can trivially mock this out to develop the front end while the backend
team actually implements the API.

Glad to see something like mirage solving this across all different types of
API frameworks.

------
nlh
This is awesome! Exactly the kind of library I’ve been looking for.

Does anyone have any suggestions on a way to start with an OpenAPI spec and
end up with a mock data set? With Mirage it seems easy enough to mock our API
directly from scratch, but if we could save a few steps and go from OpenAPI
spec to mocked front end that would be bliss.

------
kostarelo
I've used Mirage for a bit while working on an Ember project. It was really
awesome and user-friendly and easy to use.

I have been using [https://github.com/nock/nock](https://github.com/nock/nock)
in Node.js for ages and I love it as well.

------
lnenad
At our job we used to mock both frontend and backend and we needed
consistency, so to help us I developed
[https://mockadillo.com](https://mockadillo.com) which is imho easier to use
than embedding mocks in your code.

------
mupkoo
Great tool! I cannot say how much I like using Mirage, and how much it helps
me while developing applications. I have used it only with Ember.JS and I
always missed having it while using some others JS frameworks.

Much appreciated Sam and much love ️

------
dustinsoftware
We use Mirage for a large scale ordering front-end built with Ember. It’s
enabled almost zero flakiness when writing our acceptance tests; super excited
to see the library get ported outside the Ember ecosystem!

------
progx
Thank you! I hacked something similar quick and dirty, but i will use
definitely Mirage with my next project.

------
duxup
I'm a bit of a noob so hang with me here.

So you install it as a dev dependency via npm.

So is it running ... with the client app as a proxy between the client
application and just waiting for the API requests and taking those responding?

Is it possible to configure some delay in responses?

~~~
acemarke
From reading the docs and the source, it's not a proxy. It looks like it uses
[https://github.com/pretenderjs/pretender](https://github.com/pretenderjs/pretender)
, which overwrites the original `XmlHttpRequest` and `fetch` functions in the
browser to intercept any attempts to make AJAX requests. It then makes your
attempted request with its own internal routing definitions, and returns the
responses you defined.

~~~
duxup
Ah thank you!

------
fzaninotto
Nice tool. But apart from the great landing page, what's the difference with
FakeRest [0]?

0:
[https://github.com/marmelab/FakeRest](https://github.com/marmelab/FakeRest)

~~~
samselikoff
I wrote a guide because folks kept asking!
[https://miragejs.com/docs/meta/comparison-with-other-
tools](https://miragejs.com/docs/meta/comparison-with-other-tools)

------
varrock
This looks really cool. Is there a difference between this and json-server
[0]?

0: [https://github.com/typicode/json-server](https://github.com/typicode/json-
server)

~~~
acemarke
Looks like `json-server` is a real server, whereas Mirage is a tool for
mocking `XmlHttpRequest` and `fetch` on the client side in the browser.

------
Theia
Is it possible to include it as a standalone js file? Instead of using npm or
yarn?

~~~
samselikoff
Yep we publish a UMD build you can grab here:

[https://unpkg.com/browse/miragejs@0.1.33/dist/](https://unpkg.com/browse/miragejs@0.1.33/dist/)

------
philipov
Finally a library to help me make a mockery of my project!

