API Mocking'i Mirage JS ve Vue.js ile Ayarlama

Yayınlanan: 2022-03-10
Kısa özet ↬ Bu makale, herhangi bir arka uç API'sine veya hizmetine güvenmek zorunda kalmadan eksiksiz bir çalışan JavaScript uygulaması oluşturmanıza, test etmenize ve paylaşmanıza olanak tanıyan bir API alay kitaplığı olan Mirage JS'yi tanıtmaktadır. Ayrıca, aşamalı ön uç çerçevesi Vue.js ile Mirage JS'yi nasıl kuracağınızı da öğreneceksiniz.

SPA ve JAMstack çağında, API'ler ve ön uç geliştirme arasında her zaman bir endişe ayrılığı olmuştur. Vahşi doğada bulunabilen hemen hemen tüm JavaScript projeleri, bir web hizmeti veya API ile etkileşime girer ve onu kimlik doğrulama veya kullanıcıyla ilgili verileri almak için kullanır.

Bu nedenle, bir proje üzerinde çalıştığınız ve gerekli API'nin arka uç ekibi tarafından hala uygulanmadığı veya bir özelliği hızlı bir şekilde test etmeniz gerektiği zaman, aşağıdaki seçeneklerden bazılarına sahipsiniz:

  • Çoğu durumda bir ön uç geliştirici olarak sahip olamayacağınız gerçek arka ucunuzun yerel olarak çalışan bir sürümüne proxy yapabilirsiniz.
  • Gerçek isteği yorumlayabilir ve sahte verilerle değiştirebilirsiniz. (Bu sorun değil, ancak üretime geçmek için bunu geri almanız gerekeceğinden ve ağ durumları ve gecikmeyle başa çıkamayabilirsiniz kadar büyük değil.)

API Alaycılığı Nedir?

API alayı, gerçek bir API'nin taklidi veya simülasyonudur. Çoğunlukla, gerçek bir arka uç API'sine yapılması gereken istekleri engellemek için yapılır, ancak bu alay, ön uçunuzda bulunur.

API Alaycılığı Neden Önemlidir?

API alayı birçok yönden önemli ölçüde önemlidir:

  1. Özellikleri oluşturmadan önce üretim API'lerine bağımlı olmamak çok iyi bir ön uç geliştirme deneyimi sağlar.
  2. Tüm ön ucunuzu paylaşabilirsiniz ve gerçek bir arka uç API'sine bağlı olmadan çalışır.
Atlamadan sonra daha fazlası! Aşağıdan okumaya devam edin ↓

Mirage JS Nedir?

Mirage JS, 5 yıl önce oluşturuldu ve Sam Selikoff, 24 Ocak 2020'de Twitter'da yayınlandığını resmi olarak duyurmadan önce Ember topluluğunda oldukça fazla kullanıldı.

Mirage JS, arka uç API'lerini bu API'lere bağımlı olmadan test etmek için sorunlu noktayı çözer. Üretim API'lerini taklit ederek sorunsuz ön uç geliştirme deneyimi sağlar.

Mirage JS, Vue.js, React, Angular ve Ember çerçeveleri için bir API alay kitaplığıdır

Mirage JS'yi Daha İyi Bir Seçim Yapan Nedir?

API alayı için başka seçenekler de var (Axios önleyicileri, Typicode'un JSON sunucusu vb. gibi) ancak Mirage hakkında oldukça ilginç olduğunu düşündüğüm şey, geliştirme sürecinizin önüne geçmemesi (göreceğiniz gibi) Vue ile biraz kurduğumuzda). Hafif ve aynı zamanda güçlüdür.

Zamanlama seçeneğiyle yavaş bir ağı simüle etmek gibi gerçek üretim API tüketim senaryolarını çoğaltmanıza olanak tanıyan kutudan çıkan pille birlikte gelir.

Mirage JS ve Vue.js'ye Başlarken

Artık Mirage JS'nin ne olduğunu ve ön uç geliştirme iş akışınız için neden önemli olduğunu bildiğinize göre, onu aşamalı web çerçevesiyle kurmaya bakalım: Vue.js.

Yeşil Alan (Temiz Kurulum) Vue Projesi Oluşturma

Vue CLI'yi kullanarak, projenin oluşturulmasını ve çalışmasını istediğiniz dizine giderek (terminalinizde) yeni bir Vue.js projesi oluşturun:

 vue create miragejs-demo-vue

Yukarıdaki komut, şimdi cd girebileceğiniz ve ya yarn serve ya da npm run serve yeni bir Vue projesi oluşturacaktır.

#Mirage JS'yi Yükleme

Şimdi aşağıdaki komutu çalıştırarak Vue.js projemizde bir geliştirme bağımlılığı olarak Mirage JS'yi kuralım:

 yarn add -D miragejs

Veya NPM kullanıyorsanız, şunu çalıştırın:

 npm install --save-dev miragejs

Ve bu kadar! Mirage JS artık Vue.js projemize yüklendi.

Hadi Bir Şeyle Alay Edelim

Mirage JS yüklendiğinde, onu Vue ile konuşacak ve temel bir yapılacaklar (bir yapılacaklar listesi döndüren bir API) API'si ile alay edecek şekilde nasıl yapılandırdığımızı görelim.

Sunucunuzu Tanımlayın

Başlamak için Vue.js projemizin /src dizininde bir server.js dosyası oluşturmamız gerekiyor. Bundan sonra aşağıdakileri ekleyin:

 import { Server, Model } from 'miragejs' export function makeServer({ environment = "development" } = {}) { let server = new Server({ environment, models: { todo: Model, }, seeds(server) { server.create("todo", { content: "Learn Mirage JS" }) server.create("todo", { content: "Integrate With Vue.js" }) }, routes() { this.namespace = "api" this.get("/todos", schema => { return schema.todos.all() }) }, }) return server }

Kod Açıklaması

İlk olarak, server.js dosyası, uygulamanızda tanımladığınız rotalarla eşleşen tüm API çağrılarını durduracak sahte (sahte) sunucusunun yeni bir örneğini oluşturmak için Mirage JS'yi nasıl kurduğunuzdur.

Şimdi, yukarıdakilerin ilk başta bunaltıcı olabileceğine katılıyorum, ancak burada neler olduğuna daha yakından bakalım:

 import { Server, Model } from 'miragejs'

Yukarıdaki kod parçacığından, miragejs Server ve Model içe aktarıyoruz.

  • Server
    Bu, sahte sunucumuz olarak "hizmet etmek" için yeni bir Mirage JS sunucusu örneğini başlatmamıza yardımcı olmak için Mirage tarafından sunulan bir sınıftır.
  • Model
    Mirage'ın ORM'si tarafından desteklenen modeller (bir model, bir Mirage JS veritabanı girişinin yapısını belirler) oluşturmaya yardımcı olması için Mirage tarafından sunulan başka bir sınıf.
 export function makeServer({ environment = "development" } = {}) {}

Yukarıdakiler temel olarak src/server.js makeServer adlı bir işlevi dışa aktarır. Ayrıca bir ortam parametresine geçtiğimizi ve Mirage'ın ortam modunu development ayarladığımızı da not edebilirsiniz (bu makalenin ilerleyen kısımlarında test ortamından geçtiğimizi göreceksiniz).

makeServer

Şimdi makeServer gövdesinde birkaç şey yapıyoruz. Hadi bir bakalım:

 let server = new Server({})

Server sınıfının yeni bir örneğini başlatıyoruz ve ona bir yapılandırma seçeneği iletiyoruz. Yapılandırma seçeneklerinin içeriği, serap kurulumuna yardımcı olur:

 { environment, models: { todo: Model, }, seeds(server) { server.create("todo", { content: "Learn Mirage JS" }) server.create("todo", { content: "Integrate With Vue.js" }) }, routes() { this.namespace = "api" this.get("/todos", schema => { return schema.todos.all() }) }, }

İlk olarak fonksiyon tanımında başlattığımız environment parametresini geçiyoruz.

 models: { todo: Model, },

Bir sonraki seçenek olan models seçeneği, Mirage'ın alay etmesini istediğimiz farklı modellerin bir nesnesini alır.

Yukarıda, Model sınıfından somutlaştırdığımız bir yapılacaklar modeli istiyoruz.

 seeds(server) { server.create("todo", { content: "Learn Mirage JS" }) server.create("todo", { content: "Integrate With Vue.js" }) },

Sonraki seçenek, server adlı bir parametreyi alan tohum yöntemidir. Tohum yöntemi, modellerimiz için tohumlar (tohumlar ilk veriler veya Mirage'ın veritabanına bir giriştir) oluşturmaya yardımcı olur. Bizim durumumuzda yapılacaklar modelinin tohumlarını oluşturmak için şunları yapıyoruz:

 server.create("todo", { content: "Learn Mirage JS" }) server.create("todo", { content: "Integrate With Vue.js" })

bu nedenle sunucunun, ilk argüman olarak model adına karşılık gelen bir dize, ardından belirli bir tohumun özelliklerini veya niteliklerini içerecek bir nesneyi bekleyen bir create yöntemi vardır.

 routes() { this.namespace = "api" this.get("/todos", schema => { return schema.todos.all() }) },

Son olarak, çeşitli rotaları tanımlayan rotalar yöntemimiz var (rotalar bizim sahte API uç noktalarımızdır) Mirage JS alay edecek. Yöntemin gövdesine bakalım:

 this.namespace = "api"

bu satır, tüm rotalar için ad alanını ayarlar; bu, yapılacaklar rotamıza artık /api/todos'tan erişilebileceği anlamına gelir.

 this.get("/todos", schema => { return schema.todos.all() })

Yukarıdakiler bir get yolu oluşturur ve bu, this.get() yöntemini kullanarak işleyicisidir. get() yöntemi, rotayı, yani “/todos”u ve schema argüman olarak alan bir işleyici işlevini bekler. Şema nesnesi, Mirage JS bellek içi veritabanı tarafından desteklenen Mirage'ın ORM'si ile nasıl etkileşimde bulunduğunuzdur.

En sonunda:

 return schema.todos.all()

Mirage'ın ORM'si tarafından mümkün kılınan şema nesnesini kullanarak tüm yapılacak işlerimizin bir listesini döndürüyoruz.

kaynak/main.js

Böylece src/server.js kurulumunu bitirdik ama Vue bunu bilmiyor (en azından henüz değil). Şimdi bunu main.js dosyamıza şu şekilde aktaralım:

 import { makeServer } from "./server"

Ardından makeServer işlevini şöyle çağırırız:

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

Yukarıdaki if koşullu, serapın yalnızca geliştirme aşamasında çalıştığından emin olmak için bir korumadır.

Kurulum tamamlandı!

Şimdi Vue ile Miragejs kurduk. Eylemde görelim. App.vue dosyamızda içeriği siler ve aşağıdaki snippet ile değiştiririz:

 <template> <ul> <li v-for="todo in todos" v-bind:key="todo.id">{{ todo.content }}</li> </ul> </template> <script> export default { name: 'app', data() { return { todos: [] } }, created() { fetch("/api/todos") .then(res => res.json()) .then(json => { this.todos = json.todos }) } } </script>

Vue.js'ye aşina iseniz, yukarıdakiler yeni bir şey olmaz, ancak toplam olması adına yaptığımız şey, App.vue bileşenimiz oluşturulduğunda fetch kullanarak bir API isteği yapmaktır, sonra döndürülen verileri iletiyoruz. bileşen durumumuzdaki todos dizisine. Daha sonra, yapılacaklar dizisini yinelemek için bir v-for kullanıyoruz ve her yapılacak işin content özelliğini görüntülüyoruz.

Mirage JS Bölümü Nerede?

Dikkat ederseniz, App.vue bileşenimizde Mirage'a özel bir şey yapmadık, normalde yaptığımız gibi sadece bir API çağrısı yapıyoruz. Mirage'ın bu özelliği, kaputun altındaki DX nedeni için gerçekten harika, Mirage, geliştirme aşamasındayken src/server.js'de tanımlanan yollardan herhangi biriyle eşleşen istekleri engeller.

Bu oldukça kullanışlıdır, çünkü rotaların üretim API uç noktalarınızla eşleşmesi koşuluyla, bir üretim ortamındayken gerçek bir üretim sunucusuna geçmek için sizin tarafınızdan herhangi bir çalışmaya ihtiyaç duyulmaz.

Bu nedenle, Mirage JS'yi test etmek için Vue dev sunucunuzu yarn serve aracılığıyla yeniden başlatın.

İki todonun bir listesini görmelisiniz. Oldukça ilginç bulacağınız bir şey, Vue.js uygulamanızın bir parçası olarak çalışarak bu ek yükü ortadan kaldırdığı için Mirage'ı başlatmak için bir terminal komutu çalıştırmamıza gerek olmamasıdır.

Mirage JS ve Vue test araçları

Vue uygulamanızda zaten Vue Test-utils kullanıyorsanız, Mirage'ın ağ istekleriyle alay etmek için onunla kolayca çalışabileceğini bilmek heyecan verici olacaktır. Todos uygulamamızı kullanarak bir örnek kurulum görelim.

Birim testimiz için Jest kullanıyor olurduk. Dolayısıyla, takip ediyorsanız, @vue/unit-jest eklentisini şu şekilde yüklemek için Vue CLI'yi hemen hemen kullanabilirsiniz:

 vue add @vue/unit-jest

Yukarıdakiler @vue/cli-plugin-unit-jest ve @vue/test-utils geliştirme bağımlılıklarını kurarken aynı zamanda bir tests dizini ve bir jest.config.js dosyası oluşturur. Ayrıca package.json scripts bölümümüze aşağıdaki komutu ekleyecektir (oldukça temiz):

 "test:unit": "vue-cli-service test:unit"

Test Edelim!

App.vue dosyamızı şöyle görünecek şekilde güncellerdik:

 <!-- src/App.vue --> <template> <div v-if="serverError" data-test> {{ serverError }} </div> <div v-else-if="todos.length === 0" data-test> No todos! </div> <div v-else> <ul> <li v-for="todo in todos" v-bind:key="todo.id" :data-test > {{ todo.content }} </li> </ul> </div> </template> <script> export default { name: "app", data() { return { todos: [], serverError: null, } }, created() { fetch("/api/todos") .then(res => res.json()) .then(json => { if (json.error) { this.serverError = json.error } else { this.todos = json.todos } }) }, } </script>

Yukarıdaki snippet'te gerçekten epik bir şey olmuyor; sadece birim testimizle uygulayacağımız ağ testine izin verecek şekilde yapılanıyoruz.

Vue CLI zaten bizim için bir /tests klasörü eklemiş olsa da, testlerim test ettikleri bileşenlerin yakınına yerleştirildiğinde bunu çok daha iyi bir deneyim olarak görüyorum. Bu nedenle, src/ içinde bir /__tests__ klasörü oluşturun ve bunun içinde bir App.spec.js dosyası oluşturun. (Bu aynı zamanda Jest tarafından önerilen yaklaşımdır.)

 // src/__tests__/App.spec.js import { mount } from "@vue/test-utils" import { makeServer } from "../server" import App from "../App.vue" let server beforeEach(() => { server = makeServer({ environment: "test" }) }) afterEach(() => { server.shutdown() })

Birim testimizi kurmak için @vue/test-utils adresinden mount yöntemini, daha önce oluşturduğumuz Miragejs sunucusunu ve son olarak App.vue bileşenini içe aktarıyoruz.

Ardından, test ortamından geçerken Mirage JS sunucusunu başlatmak için beforeEach yaşam döngüsü işlevini kullanıyoruz. (Unutmayın, ortamı varsayılan olarak development olarak ayarladık.)

Son olarak afterEach server.shutdown sunucuyu kapatıyoruz.

Testlerimiz

Şimdi testimizi detaylandıralım (Mirage js belgelerinin hızlı başlangıç ​​bölümünü benimsiyor olacağız. Böylece, App.spec.js'niz sonunda şöyle görünecek:

 // src/__tests__/App.spec.js import { mount } from "@vue/test-utils" import { makeServer } from "./server" import App from "./App.vue" let server beforeEach(() => { server = makeServer({ environment: "test" }) }) it("shows the todos from our server", async () => { server.create("todo", { id: 1, content: "Learn Mirage JS" }) server.create("todo", { id: 2, content: "Integrate with Vue.js" }) const wrapper = mount(App) // let's wait for our vue component to finish loading data // we know it's done when the data-testid enters the dom. await waitFor(wrapper, '[data-test]') await waitFor(wrapper, '[data-test]') expect(wrapper.find('[data-test]').text()).toBe("Learn Mirage JS") expect(wrapper.find('[data-test]').text()).toBe("Integrate with Vue.js") }) it("shows a message if there are no todo", async () => { // Don't create any todos const wrapper = mount(App) await waitFor(wrapper, '[data-test]') expect(wrapper.find('[data-test]').text()).toBe("No todos!") }) // This helper method returns a promise that resolves // once the selector enters the wrapper's dom. const waitFor = function(wrapper, selector) { return new Promise(resolve => { const timer = setInterval(() => { const todoEl = wrapper.findAll(selector) if (todoEl.length > 0) { clearInterval(timer) resolve() } }, 100) }) } afterEach(() => { server.shutdown() })

Not : Burada bir yardımcı kullanıyoruz (Mirage JS belgelerinde tanımlandığı gibi). Test ettiğimiz öğelerin DOM'da ne zaman olduğunu bilmemize izin veren bir söz verir.

Şimdi yarn test:unit .

Tüm testleriniz bu noktada geçmelidir.

Mirage JS ile Farklı Sunucu Durumunu Test Etme

Farklı sunucu durumlarını test etmek için Mirage JS sunucumuzu değiştirebiliriz. Nasıl olduğunu görelim.

 // src/__tests__/App.spec.js import { Response } from "miragejs"

İlk olarak, Mirage'dan Response sınıfını içe aktarıyoruz, ardından aşağıdaki gibi yeni bir test senaryosu oluşturuyoruz:

 it("handles error responses from the server", async () => { // Override Mirage's route handler for /todos, just for this test server.get("/todos", () => { return new Response( 500, {}, { error: "The database is taking a break.", } ) }) const wrapper = mount(App) await waitFor(wrapper, '[data-test]') expect(wrapper.find('[data-test]').text()).toBe( "The database is taking a break." ) })

Testinizi çalıştırın ve hepsi geçmelidir.

Çözüm

Bu makale, sizi Mirage JS ile tanıştırmayı ve bunun nasıl daha iyi bir ön uç geliştirme deneyimi sağladığını göstermeyi amaçladı. Mirage JS'nin ele almak için oluşturduğu sorunu (gerçek bir arka uç API'si olmadan üretime hazır ön uç oluşturma) ve bunun Vue.js ile nasıl kurulacağını gördük.

Bu makale Mirage JS'nin neler yapabileceğinin yüzeyini çizmesine rağmen, başlamanız için yeterli olduğuna inanıyorum.

  • Belgeleri inceleyebilir ve Mirage JS discord sunucusuna katılabilirsiniz.
  • Bu makalenin destekleyici deposu GitHub'da mevcuttur.

Referanslar

  • Mirage Belgeleri
  • Mirage Vue Hızlı Başlangıç