Entwicklung eines Teams zur Abfrage von Daten aus der Datenbank - Teil 4, abschließend

Dies ist eine Fortsetzung der Geschichte, die hier begann und hier und hier fortgesetzt wurde .


Im letzten Teil habe ich einen Integrationstest geschrieben, der den Prozess der Initialisierung und Ausführung eines vollständigen Satzes von Handlern demonstriert, die Daten aus einer Datenbank extrahieren. Da es jedoch zu lange dauern kann, diesen Test zu schreiben und auszuführen, um nicht nur den Handler, sondern auch die Konfigurationsregeln für alle erforderlichen Abfragen an die Datenbank zu codieren, habe ich mich heute entschlossen, die modulare Version zu implementieren, mit der alles konfiguriert und ausgeführt werden kann ein Handler. Dieser Test sieht folgendermaßen aus:


describe('requestHandler', () => { const createStore = require('redux').createStore; const reducers = require('../../src/reducers.js'); const DbMock = require('../mocks/DbMock'); const db = new DbMock(); const rules = require('../../src/rules'); const dbRequest = require('../../src/storage/dbRequest'); let request = null, store = null, context = null; beforeEach(() => { store = createStore(reducers); context = { db, store, rules }; request = dbRequest.bind(context, [ 'user' ]); expect(store.getState().user).toBeNull(); expect(store.getState().error).toEqual([]); }); it('should get user from database', (done) => { const assert = checkUser.bind(context, [ done ]); store.subscribe(assert); store.dispatch({type: 'NOTE', note: { Id: 1, UserRecordId: 1 }}); request(); }); function checkUser(args) { const state = store.getState(); if(state.user === null) return; const user = state.user; expect(user.Id).toEqual(1); expect(user.Name).toEqual('Jack'); const checkIsCompleted = args[0]; checkIsCompleted(); } }); 

Ich führe die Tests aus und erhalte die Meldung, dass das Modul mit den Regeln nicht gefunden wurde. Was muss der Handler noch einmal aus den Regeln extrahieren?


  1. Der Name des Eigenschaftscontainer-Eigenschaftsschlüssels, an den der von der Datenbank empfangene Datensatz gebunden wird
  2. Der Name der Datenbanktabelle, aus der Sie den Datensatz extrahieren möchten
  3. Die Methode, die die Anforderung bildet, die an die Datenbank gesendet werden muss, um eine Antwort zu erhalten
  4. Die Dispatcher-Methode, die den von der Datenbank empfangenen Datensatz an den Statuscontainerspeicher sendet.
  5. Eine Versandmethode, die gegebenenfalls einen Fehler an den Statuscontainerspeicher sendet. Ich beschloss, zuerst die Fehler im Statuscontainer zu konsolidieren und sie dann zu behandeln.

Das Regelwerk scheint mir ein Wörterbuch ( Map ) zu sein, in dem der Schlüssel der Name der Eigenschaft des Statuscontainers ist und ich wahrscheinlich den ersten Komponententest formulieren werde:


 describe('rules', () => { const rules = require('../src/rules'); it('should contain user rules', () => { const rule = rules.get('user'); expect(rule.table).toEqual('users'); }); }); 

Ich führe die Tests durch und Jasmine sagt mir, dass ich jetzt zwei fehlgeschlagene Tests habe. Um die Aufgabe nicht zu komplizieren, beginne ich mit einer einfachen Regel, die besagt, dass meine Anforderung zum Zuweisen eines Werts zum user des Statuscontainers in die users für Daten gehen sollte. Alles scheint logisch zu sein. Ich werde, wie es mir scheint, einen kleinen Code schreiben.


 const makeRules = () => { const rules = new Map(); rules.set('user', { table: 'users' }); return rules; }; module.exports = makeRules(); 

Ich führe die Tests aus und sehe, dass nur der Test für meinen Handler abstürzt, obwohl der Fehler jetzt anders ist. Ich werde jedoch später zu diesem Test zurückkehren, wenn ich mindestens eine vollständige Regel in meinem Wörterbuch bereit habe.


Ich werde den Regelwörterbuchtest ein wenig ändern. Ich werde einen Code hinzufügen, der das Vorhandensein einer Dispatcher-Methode überprüft, die den Fehler beim Ausführen einer Datenbankabfrage behandelt:


 describe('rules', () => { const rules = require('../src/rules'); it('should contain user rules', () => { const rule = rules.get('user'); expect(rule.table).toEqual('users'); expect(rule.onError.name).toEqual('dispatchError'); expect(typeof rule.onError).toEqual('function'); }); }); 

Ich führe die Tests aus, stelle sicher, dass ich erneut zwei fehlgeschlagene Tests habe, und kehre zum Finalisieren des Factory-Methodencodes zurück, um das Regelwörterbuch zu generieren. Ich füge die Funktion dem Objektliteral der ersten Regel hinzu:


 const makeRules = () => { const rules = new Map(); rules.set('user', { table: 'users', onError: function dispatchError(error, store) { const action = { type: 'ERROR', error }; store.dispatch(action); } }); return rules; }; module.exports = makeRules(); 

Führen Sie die Tests erneut aus. Das neue Regelfragment besteht den Test erfolgreich, daher entscheide ich mich, Prüfungen für alle verbleibenden Regeln hinzuzufügen:


 describe('rules', () => { const rules = require('../src/rules'); it('should contain user rules', () => { const rule = rules.get('user'); expect(rule.table).toEqual('users'); expect(rule.onError.name).toEqual('dispatchError'); expect(typeof rule.onError).toEqual('function'); expect(rule.onSuccess.name).toEqual('dispatchUser'); expect(typeof rule.onSuccess).toEqual('function'); expect(rule.query.name).toEqual('getUserQuery'); expect(typeof rule.query).toEqual('function'); }); }); 

Ich führe Tests durch. Der Testsatz für das Regelwörterbuch gibt erneut einen Fehler aus. Ich schreibe den Code:


 const makeRules = () => { const rules = new Map(); rules.set('user', { table: 'users', onError: function dispatchError(error, store) { const action = { type: 'ERROR', error }; store.dispatch(action); }, onSuccess: function dispatchUser(user, store) { const action = { type: 'USER', user }; store.dispatch(action); }, query: function getUserQuery(store) { const state = store.getState(); if(state.note === null) return null; return { Id: state.note.UserRecordId }; } }); return rules; }; module.exports = makeRules(); 

Ich führe Tests durch. Der Test des Regelsatzes wird erneut erfolgreich durchgeführt, und es scheint mir, dass ich jetzt mit dem Schreiben von Code für die tatsächlich neue Version des Anforderns von Daten aus der Datenbank beginnen kann. Dieses Mal werde ich die Klassensyntax nicht verwenden, da ich keine Vorteile aus ihrer Verwendung sehe. Es wird viel Code auf einmal geben, da ich den getesteten Teil rücksichtslos aus der vorhandenen Anforderungsimplementierung kopiere und ihn durch eine Überprüfung ergänze, falls der Datensatz aus der Datenbank bereits extrahiert und in den Statuscontainer gestellt wurde. Also der Code:


 function dbRequest(args){ const key = args[0]; const getQuery = this.rules.get(key).query; const dispatchUser = this.rules.get(key).onSuccess; const dispatchError = this.rules.get(key).onError; const tableName = this.rules.get(key).table; const table = this.db.Model.extend({ tableName: tableName }); const state = this.store.getState(); if(state[key] !== null) return; const query = getQuery(this.store); if(query === null) return; table.where(query).fetch().then((item) => { dispatchUser(item, this.store); }).catch((error) => { dispatchError(error, this.store); }); } module.exports = dbRequest; 

Lauftests ... Trommelwirbel! Und ich sehe eine Reihe grüner Punkte. Alle Tests wurden erfolgreich abgeschlossen. Und so werde ich dem Satz einen weiteren Test hinzufügen, der die Richtigkeit der Fehlerbehandlung überprüft, bis ich vergessen habe, dass meine DbMock einen Fehler mit der DbMock 555 DbMock einen Fehler DbMock :


 it('should add error in store state', (done) => { const assert = checkErrorHasBeenAdded.bind(context, [ done ]); store.subscribe(assert); store.dispatch({type: 'NOTE', note: { Id: 1, UserRecordId: 555 }}); request(); }); function checkErrorHasBeenAdded(args){ const state = store.getState(); if(state.error.length === 0) return; const error = state.error; expect(Array.isArray(error)).toBeTruthy(); expect(error.length).toEqual(1); expect(error[0].message).toEqual('Something goes wrong!'); const checkIsCompleted = args[0]; checkIsCompleted(); } 

Ich führe die Tests erneut durch. Alles funktioniert wie erwartet. Wir können davon ausgehen, dass der korrekte Prototyp des Abfragebefehls zur Datenbank bereit ist, und zum Refactoring und Entwickeln der Regeln zum Konfigurieren von Abfragen zurückkehren, da jetzt klar ist, dass der Code zum Generieren des Regelsatzes nicht mehr lesbar ist, nachdem nur ein paar weitere Regeln im selben Format hinzugefügt wurden.

Source: https://habr.com/ru/post/de436654/


All Articles