ואם אין before בספריית הבדיקה שלך?
בימים אלה אני בונה מחדש את קורס node.js שבאתר. הגירסה החדשה תכיל המון TypeScript ותכסה בנוסף ל node גם את Deno ו Bun והמטרה שלי היא שרוב הקורס יעבוד בכל שלושת סביבות הריצה.
בגדול המצב של TypeScript בצד שרת הוא מאוד טוב וגם דינו וגם באן מספיק בשלים בשביל לכתוב עליהם, אבל מדי פעם יש שטויות ובעיות תאימות. דוגמה קטנה היא שכשטוענים את המודול test של node מתוך deno אין תמיכה ב before.
ומה אם בכל זאת אנחנו רוצים להריץ קוד לפני בדיקה? נו, תמיד אפשר להיות יצירתיים. בדוגמה מהקורס רציתי להריץ קוד שמאתחל טבלה בבסיס נתונים בזיכרון לפני שאני מריץ קוד. בהשראה מ pytest כתבתי במקום before את הפונקציה הבאה:
import { Database } from '@/db_types.ts'
import { Kysely } from 'kysely'
import { DenoSqliteDialect } from "@soapbox/kysely-deno-sqlite";
import { DB as Sqlite } from 'https://deno.land/x/sqlite/mod.ts';
export const useDB = async (test: (db: Kysely<Database>) => Promise<void>) => {
const _db = new Kysely<Database>({
dialect: new DenoSqliteDialect({
database: new Sqlite(':memory:'),
}),
});
await _db.schema
.createTable('contact_info')
.addColumn('id', 'integer', (col) => col.primaryKey())
.addColumn('name', 'text', (col) => col.notNull())
.addColumn('email', 'text', col => col.unique())
.execute()
try {
await test(_db);
} finally {
await _db.destroy();
}
}
עכשיו הבדיקה צריכה רק להפעיל את הפונקציה והיא מקבלת אוטומטית גם את קוד האיתחול וגם את קוד הניקוי. זה נראה ככה:
test('POST /contacts created a new contact', async () => {
await useDB(async db => {
await superdeno(app(db))
.post('/api/v1/contacts')
.set('Accept', 'application/json')
.send({name: "a", email: "a@gmail.com"})
.expect(200);
const res = await superdeno(app(db))
.get('/api/v1/contacts')
.set('Accept', 'application/json')
assert.deepEqual([
{ id: 1, name: "a", email: "a@gmail.com" }
], res.body);
})
});
וכן המחשבה הראשונה שלי היתה שהחיים היו מושלמים אם דברים היו עובדים בכל הסביבות. אבל במחשבה שניה אני חושב שללמוד להסתדר גם כשדברים לא עובדים כמו בספר זו גם מיומנות חשובה ששווה להראות בקורס.