工作流程技巧

Mirage 被设计成无缝地集成到您的应用程序中,如果您遵循了其中一个 快速入门,您可能已经在项目中进行了最小的设置。

一旦您对编写 Mirage 代码感到舒适,请遵循以下技巧来优化您的开发体验,并确保您和您的团队从 Mirage 中获得最大收益。

集中并共享开发和测试之间的服务器

虽然您可以使用 Mirage 在您的组件或测试文件中直接创建一次性服务器,但通常最好将您的模拟服务器定义集中起来,以便您可以在开发和测试环境之间共享它。毕竟,在生产环境中,您的应用程序将与实现单个 API 合同的单个服务器进行通信!因此,使用单个服务器定义有助于您在使用 Mirage 的所有地方维护一致的模拟 API 合同。

因此,如果您已经拥有一个用于开发或测试的 Mirage 服务器,请将其移动到一个明显的位置,表明它将在开发环境和您的测试中使用。

定义共享服务器的一个常见位置是 src/server.js

└── src
    ├── App.js
    ├── App.test.js
    └── server.js

接下来,从您的 server.js 文件中,导出一个可以用来启动 Mirage 服务器的函数

// src/server.js
import { createServer, Model } from "miragejs"

export function makeServer({ environment = 'test' }) {
  return createServer({
    environment,

    models: {
      movie: Model,
    },

    routes() {
      this.namespace = "api"

      this.resource("movie")
    },
  })
}

在这里,我们定义了 makeServer 函数来接受一个带有 environment 键的 options 参数。 test 环境关闭了 Mirage 的人工延迟,忽略任何初始 seeds(),并禁用对控制台的日志记录。由于您可能在多个测试中导入 makeServer,但在开发中只导入一次,因此将环境默认设置为 test 是一个合理的选择。当然,您可以根据项目的需要自定义该函数以接受其他任何参数。

现在,您可以在开发中导入此函数以启动 Mirage。

例如,在 React 应用程序中, index.js 通常是“引导”文件,因此您可以在那里启动 Mirage

// index.js
import React from "react"
import ReactDOM from "react-dom"
import App from "./App"
import { makeServer } from "./mirage"

makeServer({ environment: "development" })

ReactDOM.render(<App />, document.getElementById("root"))

现在,无论何时像往常一样开发 React 应用程序 (npm run start),Mirage 都会开始运行。

在生产环境中,您可能不希望 Mirage 运行(因为您的应用程序需要发出实际的网络请求),因此您最终可能会得到这样的结果

// index.js
import React from "react"
import ReactDOM from "react-dom"
import App from "./App"
import { makeServer } from "./mirage"

if (process.env.NODE_ENV === "development") {
  makeServer({ environment: "development" })
}

ReactDOM.render(<App />, document.getElementById("root"))

process.env.NODE_ENV 是设置中常见的全局变量,它公开应用程序的构建环境,可以用来有条件地启动 Mirage。

理想情况下,如果您不在生产中使用 Mirage,您应该确保 Mirage 的库代码以及您的服务器定义代码不会包含在您的生产包中(除非您正在构建原型并希望启用它)。如何实现这一点将取决于您的构建工具设置,但在很多情况下,添加上面显示的检查会自动从您的构建中移除 Mirage。

您也可以在测试中使用新的集中式服务器定义。在测试中导入您的 makeServer 函数,并在每个测试之前使用它来启动 Mirage

// tests/home-test.js
import { startMirage } from "./mirage"

describe("homepage", function () {
  let server

  beforeEach(() => {
    server = startMirage()
  })

  afterEach(() => {
    server.shutdown()
  })

  it("shows the movies", function () {
    server.createList("movie", 10)

    cy.visit("/")

    cy.get("li.movie").should("have.length", 10)
  })
})

Mirage 服务器实例有一个 shutdown 方法,您需要在每个测试之后调用该方法来清理您的环境。

请注意,即使您的测试使用共享服务器定义,您仍然可以应用一次性修改来测试您的应用程序在非典型情况下的行为。例如,如果您想测试您的应用程序如何响应 500 服务器错误,您可以只修改测试中的单个 API 路由,而不是更改全局 Mirage 服务器定义。

// tests/home-test.js
import { startMirage } from "./mirage"
import { Response } from "miragejs"

describe("homepage", function () {
  let server

  beforeEach(() => {
    server = startMirage()
  })

  afterEach(() => {
    server.shutdown()
  })

  it("shows an error if the server is down", function () {
    // Override the existing /movies route handler, just for this test
    server.get("/movies", () => new Response(500))

    cy.visit("/")

    cy.get("h1").should("contain", "Whoops! Our site is down.")
  })
})

因为您每次测试都会关闭服务器并启动一个新服务器,所以这些修改只会应用于您进行修改的测试。

现在您有一个单独的地方来定义和扩展您的 Mirage 服务器,并且有一个简单的方法可以在您的测试中使用它。