Ошибка Mirage undefined (маршрут не определен) при тестировании с Vue и Cypress

У меня Cypress работает в приложении Vue CLI, и недавно я добавил Mirage, чтобы расширить возможности имитации моей базы данных. Я выполнил руководство по быстрому запуску Mirage, чтобы использовать его в Cypress, и теперь я пытаюсь переписать свой логин тестовое задание. Логин в приложении работает с POST-запросом к конечной точке API / oauth / token, но в Cypress / Mirage он не сообщает

"Mirage: Your app tried to POST 'http://localhost:8090/oauth/token', but there was no route defined to handle this request. Define a route for this endpoint in your routes() config. Did you forget to define a namespace?"

Кажется, что маршруты из хука routes () в server.js не зарегистрированы на сервере:

import { Server, Model } from 'miragejs'

export function makeServer({ environment = 'development' } = {}) {
  let server = new Server({
    environment,

    models: {
      user: Model,
    },

    seeds(server) {
      server.create("user", { name: "Bob" })
      server.create("user", { name: "Alice" })
    },

    routes() {
      this.urlPrefix = 'http://localhost:8090'
      this.namespace = ''

      /* Login */
      this.post("/oauth/token", () => {
        return { 'access_token': 'abcd123456789', 'token_type': 'bearer', 'refresh_token': 'efgh123456789'}
      })
    }
  })

  return server
}

В хук beforeEach файла спецификации я вызываю серверную функцию:

import { makeServer } from '../../src/server'

let server

beforeEach(() => {
  server = makeServer({ environment: 'development' })
})

И еще я добавил этот блок в cypress / support / index.js, как в туториале:

Cypress.on("window:before:load", (win) => {
  win.handleFromCypress = function (request) {
    return fetch(request.url, {
      method: request.method,
      headers: request.requestHeaders,
      body: request.requestBody,
    }).then((res) => {
      let content =
        res.headers.map["content-type"] === "application/json"
          ? res.json()
          : res.text()
      return new Promise((resolve) => {
        content.then((body) => resolve([res.status, res.headers, body]))
      })
    })
  }
})

И я добавил этот блок в main.js Vue:

import { Server, Response } from "miragejs"

if (window.Cypress) {
  new Server({
    environment: "test",
    routes() {
      let methods = ["get", "put", "patch", "post", "delete"]
      methods.forEach((method) => {
        this[method]("/*", async (schema, request) => {
          let [status, headers, body] = await window.handleFromCypress(request)
          return new Response(status, headers, body)
        })
      })
    },
  })
}

«Тест» среды в main.js не имеет значения, если я изменю его на «разработка».

Есть ли способ узнать, какие маршруты зарегистрированы на моем сервере в любой момент времени выполнения сервера? При отладке сервера в моей спецификации атрибут routes сервера имеет длину 0. Определил ли я свои маршруты в неправильное время или в неправильном месте?

ОБНОВЛЕНИЕ: я понял, что могу использовать рабочий маршрут Mirage в моем локальном веб-приложении, когда я создаю сервер в Vue main.js, как описано здесь вместо использования инфраструктуры Cypress. Итак, теперь я думаю, что определение маршрута в порядке, и проблема должна быть внутри кода для перехвата запросов Cypress.


person J. Unkrass    schedule 07.04.2020    source источник


Ответы (1)


Наконец-то я нашел решение с помощью Сэма Селикоффа на канале раздора Mirage. Моя проблема заключалась в том, что мой API работает на другом порту, чем мое приложение.

Как сказал Сэм о разногласиях (я немного перефразировал):

По умолчанию this.passthrough() работает только для запросов в текущем домене. Код из шага 4 краткого руководства в main.js Vue должен сказать

this[method]("http://localhost:8090/*", async...

вместо того

this[method]("/*", async...

Надеюсь, это кому-то поможет в будущем. Это стоило мне целой недели.

person J. Unkrass    schedule 10.04.2020