docs: def request(self, rule, view_class, annotation):
          """Make a request against the app.
  
          This attempts to use the schema to replace any url params in the path
          pattern. If there are any unused parameters in the schema, after
          substituting the ones in the path, they will be sent as query string
          parameters or form parameters. The substituted values are taken from
          the "example" value in the schema.
  
          Returns a dict with the following keys:
  
          - **url** -- Example URL, with url_prefix added to the path pattern,
            and the example values substituted in for URL params.
          - **method** -- HTTP request method (e.g. "GET").
          - **params** -- A dictionary of query string or form parameters.
          - **response** -- The text response to the request.
  
          :param route: Werkzeug Route object.
          :param view_class: View class for the annotated method.
          :param annotation: Annotation for the method to be requested.
          :type annotation: doctor.resource.ResourceAnnotation
          :returns: dict
          """
          headers = self._get_headers(rule, annotation)
          example_values = self._get_example_values(rule, annotation)
          # If any of the example values for DELETE/GET HTTP methods are dicts
          # or lists, we will need to json dump them before building the rule,
          # otherwise the query string parameter won't get parsed correctly
          # by doctor.
          if annotation.http_method.upper() in ('DELETE', 'GET'):
              for key, value in list(example_values.items()):
                  if isinstance(value, (dict, list)):
                      example_values[key] = json.dumps(value)
          _, path = rule.build(example_values, append_unknown=True)
          if annotation.http_method.upper() not in ('DELETE', 'GET'):
              parsed_path = parse.urlparse(path)
              path = parsed_path.path
              params = example_values
          else:
              params = {}
          method_name = annotation.http_method.lower()
          method = getattr(self.test_client, method_name)
          if method_name in ('post', 'put'):
              response = method(path, data=json.dumps(params), headers=headers,
                                content_type='application/json')
          else:
              response = method(path, data=params, headers=headers)
          return {
              'url': '/'.join([self.url_prefix, path.lstrip('/')]),
              'method': annotation.http_method.upper(),
              'params': params,
              'response': response.data,
          }