前端開發的最佳開發體驗。
告別為了在 UI 上進行修改而必須設定繁瑣的後端環境。Mirage 與您其餘的前端程式碼一起執行,因此您無需學習新的基礎架構。
新的協作者可以複製您的前端程式碼庫、執行 npm install,並在幾秒鐘內啟動並執行完整的本機離線開發環境 — 無需環境變數或驗證權杖。
import React from "react"
import ReactDOM from "react-dom"
import App from "./App"
import { createServer } from "miragejs"
createServer({
routes() {
this.namespace = "api"
this.get("/todos", ({ db }) => {
return db.todos
})
},
})
ReactDOM.render(<App />, document.getElementById("root"))
自 2015 年以來,我們一直在 Heroku 上針對重要的客戶應用程式使用 Mirage。它使我們的團隊能夠成長,而不會犧牲開發或測試工作流程的速度。
對我而言,Mirage 的真正魔力在於它讓我們可以從使用者的角度編寫測試。我們從產品團隊中獲取使用者故事,並將它們 1:1 轉化為測試,而無需透過離開前端工具鏈來中斷流程。
簡而言之,Mirage 是每個 UI 開發人員必備的工具。
Salesforce/Heroku 的軟體工程師
編寫 高階 UI 測試 來測試您的網路程式碼。
使用 Mirage,無論 API 處於何種狀態,您都可以針對 API 編寫自動化測試。測試您的應用程式如何處理 0 篇、10 篇或 1000 篇部落格文章,甚至在伺服器速度緩慢或回應錯誤時的行為。
您的測試中沒有雜亂的模擬程式碼或手工製作的 API 回應。只有驗證整個應用程式完整功能的真實情境。

it("shows a message if there are no todos", async () => {
const { getByTestId } = render(<App />)
await waitForElementToBeRemoved(() => getByTestId("loading"))
expect(getByTestId("no-todos")).toBeInTheDocument()
})
it("shows existing todos", async () => {
server.createList("todo", 3)
const { getByTestId, getAllByTestId } = render(<App />)
await waitForElementToBeRemoved(() => getByTestId("loading"))
expect(getAllByTestId("todo")).toHaveLength(3)
})
it("can complete a todo", async () => {
server.create("todo", { text: "Todo 1", isDone: false })
server.create("todo", { text: "Todo 2", isDone: false })
const { getByTestId, getAllByTestId } = render(<App />)
await waitForElementToBeRemoved(() => getByTestId("loading"))
const todos = getAllByTestId("todo")
userEvent.click(todos[1].querySelector("input[type='checkbox']"))
await waitForElementToBeRemoved(() => getByTestId("saving"))
expect(todos[0].querySelector('input[type="checkbox"]').checked).toBe(false)
expect(todos[1].querySelector('input[type="checkbox"]').checked).toBe(true)
expect(server.db.todos[1].isDone).toBe(true)
})
it("can create a todo", async () => {
const { getByTestId } = render(<App />)
await waitForElementToBeRemoved(() => getByTestId("loading"))
const newTodoForm = await waitForElement(() => getByTestId("new-todo-form"))
userEvent.type(newTodoForm.querySelector("input"), "Walk the dog")
fireEvent.submit(getByTestId("new-todo-form"))
await waitForElementToBeRemoved(() => getByTestId("saving"))
const todo = getByTestId("todo")
expect(todo.querySelector('input[type="checkbox"]').checked).toBe(false)
expect(todo.querySelector('input[type="text"]').value).toBe("Walk the dog")
expect(server.db.todos.length).toBe(1)
expect(server.db.todos[0].text).toBe("Walk the dog")
})
it("shows a message if there are no todos", async () => {
const { getByTestId } = render(<App />)
await waitForElementToBeRemoved(() => getByTestId("loading"))
expect(getByTestId("no-todos")).toBeInTheDocument()
})
it("shows existing todos", async () => {
server.createList("todo", 3)
const { getByTestId, getAllByTestId } = render(<App />)
await waitForElementToBeRemoved(() => getByTestId("loading"))
expect(getAllByTestId("todo")).toHaveLength(3)
})
it("can complete a todo", async () => {
server.create("todo", { text: "Todo 1", isDone: false })
server.create("todo", { text: "Todo 2", isDone: false })
const { getByTestId, getAllByTestId } = render(<App />)
await waitForElementToBeRemoved(() => getByTestId("loading"))
const todos = getAllByTestId("todo")
userEvent.click(todos[1].querySelector("input[type='checkbox']"))
await waitForElementToBeRemoved(() => getByTestId("saving"))
expect(todos[0].querySelector('input[type="checkbox"]').checked).toBe(false)
expect(todos[1].querySelector('input[type="checkbox"]').checked).toBe(true)
expect(server.db.todos[1].isDone).toBe(true)
})
it("can create a todo", async () => {
const { getByTestId } = render(<App />)
await waitForElementToBeRemoved(() => getByTestId("loading"))
const newTodoForm = await waitForElement(() => getByTestId("new-todo-form"))
userEvent.type(newTodoForm.querySelector("input"), "Walk the dog")
fireEvent.submit(getByTestId("new-todo-form"))
await waitForElementToBeRemoved(() => getByTestId("saving"))
const todo = getByTestId("todo")
expect(todo.querySelector('input[type="checkbox"]').checked).toBe(false)
expect(todo.querySelector('input[type="text"]').value).toBe("Walk the dog")
expect(server.db.todos.length).toBe(1)
expect(server.db.todos[0].text).toBe("Walk the dog")
})
分享 完全運作的 UI 而無需執行後端。
由於 Mirage 真實地模擬了您的整個 API 伺服器,因此您可以在無需執行任何後端服務的情況下,分享可點擊、運作的 JavaScript 應用程式原型。
在您開始投資昂貴的伺服器端基礎架構之前,先從您的使用者那裡獲得高品質的回饋,並以前所未有的速度進行迭代。

老實說,我對這個工具的推薦程度再高也不為過。終於,前端開發人員有了一種慣用的方法來建立原型並測試整個功能,而無需接觸真實的 API!生產力直線上升。
500tech 的開發人員