[HN Gopher] MirageJS: An API mocking library for frontend develo... ___________________________________________________________________ MirageJS: An API mocking library for frontend development Author : mixonic Score : 126 points Date : 2020-01-24 18:53 UTC (4 hours ago) (HTM) web link (miragejs.com) (TXT) w3m dump (miragejs.com) | ravenstine wrote: | 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. | SaladFork wrote: | 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. | progx wrote: | Thank you! I hacked something similar quick and dirty, but i will | use definitely Mirage with my next project. | dustinsoftware wrote: | 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! | rubyn00bie wrote: | 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 wrote: | 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. | acemarke wrote: | Off the top of my head, the import logic could be something | like: if(__DEV__) { | require("loadApiMocking"); } | | Agreed that there'd be work to do to keep real code responses | and mocked responses in sync, but there's probably ways to | automate that if you want. In fact, I can hypothetically | imagine some way to introspect OpenAPI schema files and | configure Mirage accordingly. | samselikoff wrote: | 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. | jgwhite wrote: | > how does it provide a sanity check between what the back | end delivers and the front end expects | | The team I work on have been using Mirage with GraphQL for 6 | months or so and GraphQL's tooling almost entirely addresses | this question. There will still be false positives in API | _behaviour_ (you can never have a completely accurate | simulation) but you can get an incredible degree of | confidence at a startlingly low cost, with a delight | developer experience to boot. Similar strategies could no | doubt be employed for JSONSchema, Swagger, or Pact tooling. | duxup wrote: | 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 wrote: | From reading the docs and the source, it's not a proxy. It | looks like it uses 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 wrote: | Ah thank you! | quaunaut wrote: | 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. | samselikoff wrote: | 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 wrote: | 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. | linux2647 wrote: | Thank you so much for putting this together! When I did | Ember.js development, this was one of the features I missed the | most when using other JS frameworks. | zackify wrote: | 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 wrote: | 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. ) | ibero wrote: | 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. | hinkley wrote: | 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 wrote: | 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 ___________________________________________________________________ (page generated 2020-01-24 23:00 UTC)