Mirage JS Deep Dive: Fabrikaları, Fikstürleri ve Serileştiricileri Anlama (Bölüm 2)
Yayınlanan: 2022-03-10Bu dizinin önceki makalesinde, Mirage ile ilgili oldukları için Modeller ve Dernekler üzerinde çalıştık. Modellerin, sahte uç noktalarımıza bir istekte bulunduğunda Mirage'ın uygulamamıza hizmet edeceği dinamik sahte veriler oluşturmamıza izin verdiğini açıkladım. Bu makalede, daha da hızlı API alayı sağlayan diğer üç Mirage özelliğine bakacağız. Hemen dalalım!
Not : Burada tartışılacaklar hakkında gerçekten sağlam bir kavrayışa sahip değilseniz, ilk iki makalemi okumanızı şiddetle tavsiye ederim. Bununla birlikte, yine de takip edebilir ve gerektiğinde önceki makalelere başvurabilirsiniz.
- API Mocking'i Mirage JS ve Vue ile Ayarlama
- Mirage JS Modelleri ve Dernekleri
fabrikalar
Bir önceki yazımda, arka uç API'sini taklit etmek için Mirage JS'nin nasıl kullanıldığını açıklamıştım, şimdi Mirage'da bir ürün kaynağı ile alay ettiğimizi varsayalım. Bunu başarmak için, belirli bir uç noktaya yönelik istekleri durdurmaktan sorumlu olacak bir rota işleyicisi oluştururuz ve bu durumda uç nokta api/products
olur. Oluşturduğumuz rota işleyicisi tüm ürünleri döndürecektir. Mirage'da bunu başarmak için kod aşağıdadır:
import { Server, Model } from 'miragejs'; new Server({ models: { product: Model, }, routes() { this.namespace = "api"; this.get('products', (schema, request) => { return schema.products.all() }) } }); },
Yukarıdakilerin çıktısı şöyle olacaktır:
{ "products": [] }
Yukarıdaki çıktıdan ürün kaynağının boş olduğunu görüyoruz. Ancak, henüz herhangi bir kayıt oluşturmadığımız için bu bekleniyor.
Profesyonel İpucu : Mirage, geleneksel API uç noktaları için ihtiyaç duyulan kısayolu sağlar. Bu nedenle, yukarıdaki rota işleyici de şu kadar kısa olabilir: this.get('/products')
.
Server
örneğimizde seeds
yöntemini kullanarak Mirage veritabanında saklanacak product
modelinin kayıtlarını oluşturalım:
seeds(server) { server.create('product', { name: 'Gemini Jacket' }) server.create('product', { name: 'Hansel Jeans' }) },
Çıktı:
{ "products": [ { "name": "Gemini Jacket", "id": "1" }, { "name": "Hansel Jeans", "id": "2" } ] }
Yukarıda görebileceğiniz gibi, frontend uygulamamız /api/products
için bir istekte bulunduğunda, seeds
yönteminde tanımlandığı gibi bir ürün koleksiyonunu geri alacaktır.
Mirage'ın veritabanını tohumlamak için seeds
yöntemini kullanmak, her girişi bir nesne olarak manuel olarak oluşturmaktan bir adımdır. Ancak yukarıdaki modeli kullanarak 1000 (veya bir milyon) yeni ürün kaydı oluşturmak pratik olmayacaktır. Bu nedenle fabrikalara ihtiyaç duyulmaktadır.
Fabrikalar Açıklandı
Fabrikalar, yeni veritabanı kayıtları oluşturmanın daha hızlı bir yoludur. Mirage JS veritabanında saklanacak varyasyonlarla belirli bir modelin birden çok kaydını hızlı bir şekilde oluşturmamıza izin veriyorlar.
Fabrikalar ayrıca, bu verileri tek tek tohumlamak zorunda kalmadan gerçekçi görünen veriler oluşturmayı kolaylaştıran nesnelerdir. Fabrikalar, modellerden kayıtlar oluşturmak için daha çok tarifler veya planlardır .
Fabrika Yaratmak
Bir Fabrika oluşturarak inceleyelim. Oluşturacağımız fabrika, Mirage JS veritabanımızda yeni ürünler oluşturmak için bir plan olarak kullanılacaktır.
import { Factory } from 'miragejs' new Server({ // including the model definition for a better understanding of what's going on models: { product: Model }, factories: { product: Factory.extend({}) } })
Yukarıdan, Server
örneğimize bir factories
özelliği eklediğimizi ve bunun içinde, geleneksel olarak bir fabrika oluşturmak istediğimiz modelle aynı ada sahip başka bir özellik tanımladığımızı görürsünüz, bu durumda, bu model product
modeli. Yukarıdaki pasaj, Mirage JS'de fabrikalar oluştururken izleyeceğiniz modeli göstermektedir.
product
modeli için bir fabrikamız olmasına rağmen, buna gerçekten özellik eklemedik. Bir fabrikanın özellikleri, dizeler , booleanlar veya sayılar gibi basit türler veya aşağıda yeni ürün fabrikamızın tam uygulamasında göreceğimiz gibi dinamik verileri döndüren işlevler olabilir:
import { Server, Model, Factory } from 'miragejs' new Server({ models: { product: Model }, factories: { product: Factory.extend({ name(i) { // i is the index of the record which will be auto incremented by Mirage JS return `Awesome Product ${i}`; // Awesome Product 1, Awesome Product 2, etc. }, price() { let minPrice = 20; let maxPrice = 2000; let randomPrice = Math.floor(Math.random() * (maxPrice - minPrice + 1)) + minPrice; return `$ ${randomPrice}`; }, category() { let categories = [ 'Electronics', 'Computing', 'Fashion', 'Gaming', 'Baby Products', ]; let randomCategoryIndex = Math.floor( Math.random() * categories.length ); let randomCategory = categories[randomCategoryIndex]; return randomCategory; }, rating() { let minRating = 0 let maxRating = 5 return Math.floor(Math.random() * (maxRating - minRating + 1)) + minRating; }, }), }, })
Yukarıdaki kod parçacığında, fabrika yeni bir ürün kaydı oluşturmak için her kullanıldığında dinamik veriler oluşturmak için Math.random
aracılığıyla bir javascript mantığı belirliyoruz. Bu, Fabrikaların gücünü ve esnekliğini gösterir.
Yukarıda tanımladığımız fabrikayı kullanarak bir ürün oluşturalım. Bunu yapmak için server.create
diyoruz ve model adını ( product
) bir dize olarak iletiyoruz. Mirage daha sonra tanımladığımız ürün fabrikasını kullanarak bir ürünün yeni kaydını oluşturacaktır. Bunu yapmak için ihtiyacınız olan kod aşağıdaki gibidir:
new Server({ seeds(server) { server.create("product") } })
Profesyonel İpucu : Mirage'ın veritabanındaki kayıtları görmek için console.log(server.db.dump())
çalıştırabilirsiniz.
Aşağıdakine benzer yeni bir kayıt oluşturuldu ve Mirage veritabanında saklandı.
{ "products": [ { "rating": 3, "category": "Computing", "price": "$739", "name": "Awesome Product 0", "id": "1" } ] }
ağır basan fabrikalar
Bir fabrika tarafından sağlanan değerlerin bazılarını veya daha fazlasını, bunları şu şekilde açıkça ileterek geçersiz kılabiliriz:
server.create("product", {name: "Yet Another Product", rating: 5, category: "Fashion" })
Ortaya çıkan kayıt şuna benzer olacaktır:
{ "products": [ { "rating": 5, "category": "Fashion", "price": "$782", "name": "Yet Another Product", "id": "1" } ] }
liste oluştur
Bir fabrika yerindeyken, createList
adlı sunucu nesnesinde başka bir yöntem kullanabiliriz. Bu yöntem, model adını ve oluşturulmasını istediğiniz kayıt sayısını girerek belirli bir modelin birden çok kaydının oluşturulmasını sağlar. Aşağıda kullanımı:
server.createList("product", 10)
Veya
server.createList("product", 1000)
Gözlemleyeceğiniz gibi, yukarıdaki createList
yöntemi iki argüman alır: bir dizge olarak model adı ve oluşturulacak kayıtların sayısını temsil eden sıfırdan farklı bir pozitif tamsayı. Yukarıdakilerden yola çıkarak, az önce 500 ürün kaydı oluşturduk! Bu model, bu serinin gelecekteki bir makalesinde göreceğiniz gibi, UI testi için kullanışlıdır.
Armatürler
Yazılım testinde, bir test fikstürü veya fikstürü , testleri çalıştırmak için temel olarak hizmet eden bir dizi veya nesne koleksiyonunun bir durumudur. Bir fikstürün temel amacı, sonuçların tekrarlanabilir olmasını sağlamak için test ortamının iyi bilinmesini sağlamaktır.
Mirage, fikstürler oluşturmanıza ve bunları veritabanınızı ilk verilerle tohumlamak için kullanmanıza olanak tanır.
Not : Maketlerinizi daha bakımlı hale getirdikleri için fabrikaların 10'dan 9'unu kullanmanız önerilir.
Fikstür Oluşturma
Veritabanımıza veri yüklemek için basit bir fikstür oluşturalım:
fixtures: { products: [ { id: 1, name: 'T-shirts' }, { id: 2, name: 'Work Jeans' }, ], },
Yukarıdaki veriler otomatik olarak Mirage'ın ilk verileri olarak veritabanına yüklenir. Ancak, tanımlanmış bir tohum işleviniz varsa, Mirage, geçersiz kılınmasını istediğiniz varsayımlarla fikstürünüzü yok sayar ve bunun yerine verilerinizi tohumlamak için fabrikaları kullanır.
Fabrika Bağlantılı Armatürler
Mirage, Fikstürleri Fabrikaların yanında kullanmanız için hükümler sunar. Bunu server.loadFixtures()
çağırarak başarabilirsiniz. Örneğin:
fixtures: { products: [ { id: 1, name: "iPhone 7" }, { id: 2, name: "Smart TV" }, { id: 3, name: "Pressing Iron" }, ], }, seeds(server) { // Permits both fixtures and factories to live side by side server.loadFixtures() server.create("product") },
Fikstür dosyaları
İdeal olarak, fikstürlerinizi server.js
ayrı bir dosyada oluşturmak ve içe aktarmak istersiniz. Örneğin, fixtures
adında bir dizin oluşturabilir ve bunun içinde products.js
oluşturabilirsiniz. products.js
ekleyin:
// <PROJECT-ROOT>/fixtures/products.js export default [ { id: 1, name: 'iPhone 7' }, { id: 2, name: 'Smart TV' }, { id: 3, name: 'Pressing Iron' }, ];
Ardından server.js
ürün fikstürünü şu şekilde içe aktarın ve kullanın:
import products from './fixtures/products'; fixtures: { products, },
Fikstür nesnesinin products
özelliğine içe aktarılan ürünler dizisini atamak için ES6 özelliği kısayolunu kullanıyorum.
server.loadFixtures()
kullanarak yapmamasını açıkça söylemediğiniz sürece, testler sırasında fikstürlerin Mirage JS tarafından göz ardı edileceğini belirtmekte fayda var.
Fabrikalar ve Fikstürler
Bana göre, fabrikalardan daha uygun oldukları özel bir kullanım durumunuz dışında armatür kullanmaktan kaçınmalısınız. Fikstürler daha ayrıntılı olma eğilimindedir, fabrikalar daha hızlıdır ve daha az tuş vuruşu içerir.
serileştiriciler
Ön uca, dolayısıyla serileştiricilere beklenen bir JSON yükünü döndürmek önemlidir.
Serileştirici, rota işleyicilerinizden döndürülen bir **Model** veya **Koleksiyon**'u ön uç uygulamanızın beklediği şekilde biçimlendirilmiş bir JSON yüküne dönüştürmekten sorumlu bir nesnedir.
Mirage Belgeleri
Örneğin bu rota işleyicisini ele alalım:
this.get('products/:id', (schema, request) => { return schema.products.find(request.params.id); });
Bir Serileştirici, yanıtı şöyle bir şeye dönüştürmekten sorumludur:
{ "product": { "rating": 0, "category": "Baby Products", "price": "$654", "name": "Awesome Product 1", "id": "2" } }
Mirage JS Yerleşik Serileştiriciler
Mirage JS serileştiricileriyle çalışmak için, hangi yerleşik serileştiriciyle başlayacağınızı seçmeniz gerekir. Bu karar, arka ucunuzun nihayetinde ön uç uygulamanıza göndereceği JSON türünden etkilenecektir. Mirage, aşağıdaki serileştiricilerle birlikte gelir:
-
JSONAPISerializer
Bu seri hale getirici JSON:API spesifikasyonunu takip eder. -
ActiveModelSerializer
Bu serileştirici, active_model_serializer gem ile oluşturulmuş Rails API'lerine benzeyen API'leri taklit etmek için tasarlanmıştır. -
RestSerializer
RestSerializer
, diğer yaygın API'ler için Mirage JS "catch all" serileştiricisidir.
Serileştirici Tanımı
Bir serileştirme tanımlamak için, uygun serileştiriciyi örneğin RestSerializer
miragejs
şekilde içe aktarın:
import { Server, RestSerializer } from "miragejs"
Ardından Server
örneğinde:
new Server({ serializers: { application: RestSerializer, }, })
RestSerializer
, varsayılan olarak Mirage JS tarafından kullanılır. Bu nedenle, açıkça ayarlamak gereksizdir. Yukarıdaki snippet örnek amaçlıdır.
Hem JSONAPISerializer
hem de ActiveModelSerializer
çıktısını yukarıda tanımladığımız aynı rota işleyicisinde görelim.
JSONAPISerializer
import { Server, JSONAPISerializer } from "miragejs" new Server({ serializers: { application: JSONAPISerializer, }, })
Çıktı:
{ "data": { "type": "products", "id": "2", "attributes": { "rating": 3, "category": "Electronics", "price": "$1711", "name": "Awesome Product 1" } } }
ActiveModelSerializer
ActiveModelSerializer'ı iş başında görmek için, ürün fabrikasındaki category
bildirimini şu şekilde değiştirirdim:
productCategory() { let categories = [ 'Electronics', 'Computing', 'Fashion', 'Gaming', 'Baby Products', ]; let randomCategoryIndex = Math.floor( Math.random() * categories.length ); let randomCategory = categories[randomCategoryIndex]; return randomCategory; },
Tek yaptığım, seri hale getiricinin onu nasıl idare edeceğini göstermek için özelliğin adını productCategory
olarak değiştirmekti.
Ardından ActiveModelSerializer
serileştiricisini şu şekilde tanımlarız:
import { Server, ActiveModelSerializer } from "miragejs" new Server({ serializers: { application: ActiveModelSerializer, }, })
Serileştirici, döndürülen JSON'u şu şekilde dönüştürür:
{ "rating": 2, "product_category": "Computing", "price": "$64", "name": "Awesome Product 4", "id": "5" }
productCategory'nin Ruby ekosisteminin productCategory
gem ile uyumlu product_category
dönüştürüldüğünü fark edeceksiniz.
Serileştiricileri Özelleştirme
Mirage, bir seri hale getiriciyi özelleştirme yeteneği sağlar. Diyelim ki uygulamanız öznitelik adlarınızın camelcase olmasını gerektiriyor, bunu başarmak için RestSerializer
geçersiz kılabilirsiniz. lodash
yardımcı program kitaplığını kullanıyor olacağız:
import { RestSerializer } from 'miragejs'; import { camelCase, upperFirst } from 'lodash'; serializers: { application: RestSerializer.extend({ keyForAttribute(attr) { return upperFirst(camelCase(attr)); }, }), },
Bu, şu şekilde JSON üretmelidir:
{ "Rating": 5, "ProductCategory": "Fashion", "Price": "$1386", "Name": "Awesome Product 4", "Id": "5" }
Toplama
Başardın! Umarım, bu makale aracılığıyla Mirage hakkında daha derin bir anlayışa sahip olmuşsunuzdur ve fabrikaları, demirbaşları ve serileştiricileri kullanmanın Mirage ile daha fazla üretim benzeri API alayı oluşturmanıza nasıl olanak sağlayacağını da görmüşsünüzdür.
- Bölüm 1: Mirage JS Modellerini ve İlişkilendirmeleri Anlama
- Bölüm 2: Fabrikaları, Fikstürleri ve Serileştiricileri Anlama
- Bölüm 3: Zamanlamayı, Yanıtı ve Geçişi Anlama
- Bölüm 4: UI Testi İçin Mirage JS ve Cypress'i Kullanma