使用 Vue 和 Cypress 测试时出现 Mirage 未定义错误(未定义路由)
Mirage undefined error (no route defined) when testing with Vue and Cypress
我在 Vue CLI 应用程序中安装了 Cypress 运行,并且最近添加了 Mirage 来扩展我的数据库模拟。我跟随 Mirage's quickstart tutorial 在 Cypress 中使用它,现在我正在尝试重写我的登录测试。应用程序中的登录与对 API 端点 /oauth/token 的 POST 请求一起工作,但在 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?"
server.js 中 routes() 钩子的路由似乎没有注册到服务器:
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
}
在 spec 文件的 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]))
})
})
}
})
然后我将这个块添加到 Vue 的 main.js:
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 中的环境 'test' 如果我将其更改为 'development' 没有任何区别。
有什么方法可以在服务器运行时的任何时候查看哪些路由已注册到我的服务器?在我的规范中调试服务器时,服务器的路由属性长度为0。我是否在错误的时间或地点定义了路由?
更新:当我按照 here 所述在 Vue main.js 中创建服务器时,我发现我可以在本地 Web 应用程序中使用有效的 Mirage 路由,而不是使用 Cypress 框架。所以现在我认为路由定义没问题,问题一定出在Cypress的请求拦截代码中。
我终于在 Mirage 的 discord 频道上的 Sam Selikoff 的帮助下找到了解决方案。我的问题是我的 API 与我的应用程序在不同的端口上 运行。
正如 Sam 在 discord 中所说的(我改写了一下):
By default this.passthrough()
only works for requests on the current
domain. The code from Step 4 of the quickstart in Vue's main.js needs
to say
this[method]("http://localhost:8090/*", async...
instead of
this[method]("/*", async...
我希望这对以后的人有所帮助。这花了我整整一个星期。
我在 Vue CLI 应用程序中安装了 Cypress 运行,并且最近添加了 Mirage 来扩展我的数据库模拟。我跟随 Mirage's quickstart tutorial 在 Cypress 中使用它,现在我正在尝试重写我的登录测试。应用程序中的登录与对 API 端点 /oauth/token 的 POST 请求一起工作,但在 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?"
server.js 中 routes() 钩子的路由似乎没有注册到服务器:
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
}
在 spec 文件的 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]))
})
})
}
})
然后我将这个块添加到 Vue 的 main.js:
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 中的环境 'test' 如果我将其更改为 'development' 没有任何区别。
有什么方法可以在服务器运行时的任何时候查看哪些路由已注册到我的服务器?在我的规范中调试服务器时,服务器的路由属性长度为0。我是否在错误的时间或地点定义了路由?
更新:当我按照 here 所述在 Vue main.js 中创建服务器时,我发现我可以在本地 Web 应用程序中使用有效的 Mirage 路由,而不是使用 Cypress 框架。所以现在我认为路由定义没问题,问题一定出在Cypress的请求拦截代码中。
我终于在 Mirage 的 discord 频道上的 Sam Selikoff 的帮助下找到了解决方案。我的问题是我的 API 与我的应用程序在不同的端口上 运行。
正如 Sam 在 discord 中所说的(我改写了一下):
By default
this.passthrough()
only works for requests on the current domain. The code from Step 4 of the quickstart in Vue's main.js needs to saythis[method]("http://localhost:8090/*", async...
instead of
this[method]("/*", async...
我希望这对以后的人有所帮助。这花了我整整一个星期。