meeshkan / unmock-python

Public API mocking for Python
6 stars 3 forks source link

Use a fluent API like HTTPretty and pook for mock definition #64

Open mikesol opened 5 years ago

mikesol commented 5 years ago

We should use the same fluent API as the JS library for defining specs. This is This is similar to HTTPretty and pook with the notable difference that we are generating schemas instead of hardcoded responses. As a result, this requires several additional sub-projects.

  1. A JSON Schema library, not unlike json-schema-strictly-typed. Type safety will probably be a lot harder in Python, especially intersection types. I think mypy currently cannot handle intersections. So we may need to give up on some of the sweet type safety that we can get with languages like TypeScript and Haskell.
  2. A way to compose the JSON schema, not unlike json-schema-poet. This will probably be easier, but again the typing will be a challenge if we decide to go down that route. FYI, this is used in Unmock JS here, so there is a clean separation between the JSON library and its usage in unmock.
  3. A random data generator. There are already plenty of faker libraries in Python, so if we nail the JSON schema bit, this should be the least hard element of this sequence.

Currently, unmock-py just takes a request and serves a user-defined response without using a schema, so it is not clear where these JSON schemas should live. In unmock-js, they live in a global schema store, which is kinda hacky but works. There are several ways to do it in python - global store, injecting them into tests via decorators, etc. Because python has better inversion of control and test runners, we can probably have a much cleaner interface in python for schema storage and activation than in JS.

mikesol commented 5 years ago

To kickstart this, I've created two supplemental repos that IMO will be necessary to pull this off:

Both of these have analogs in the JS world:

The one thing that'll be really hard to get right is typing. Because TypeScript is so mature, we've been able to implement Haskellian typing for all of the JSON Schema manipulations, which leads to really precise messages from the IDE if any parameters are off. Because python is missing several key features from TS-land (ie intersection types are impossible, even when using the new TypedDict), this sort of thing is not possible. That doesn't mean we should forego typing, but it does mean that the extension type system I describe here is not possible.

One solution is to use strict typing without extension types, which means that we are locked to the JSON schema syntax and cannot extend it without mypy failing our build. The other is to specialize JSON schema only for our use case, but that defeats the purpose of building a generic library.