Codice di refactoring che utilizza un elenco globale e un elenco di aggiornamenti in base ai messaggi provenienti da un sistema esterno

0

Sto refactoring del codice in cui un elenco definito a livello globale viene aggiornato in base ai messaggi provenienti da un sistema esterno. Attualmente esiste un'istanza globale della lista. Vari messaggi aggiornano l'elenco in base a regole specifiche del dominio.

Vorrei scrivere un test unitario in grado di testare il meccanismo di invio di un messaggio e controllare che l'elenco sia aggiornato correttamente.

Posso modificare il codice come ritengo opportuno. Idealmente, fallo in modo incrementale, tuttavia, poiché il programma nell'ambiente di test deve continuare a funzionare durante il refactoring.

Un'idea che avevo era di scrivere una funzione che è usata per aggiornare la lista. La funzione agisce su qualsiasi elenco passato come parametro.

In questo modo un test unitario può utilizzare il proprio elenco e verificare che, ad esempio, il messaggio X comporti il corretto aggiornamento dell'elenco.

È un approccio ragionevole? qualche altra alternativa?

L'ambiente specifico è node.js. Ma probabilmente si applica a qualsiasi lingua o ambiente.

    
posta user619818 03.05.2018 - 16:12
fonte

1 risposta

3

Esattamente, trasformare lo stato globale in oggetti passati come parametri è il modo standard per rendere una funzione verificabile.

Quindi da questo:

var globalList = [];

function doSomething() {
  ...
}

Andremmo a:

var globalList = [];

function doSomething() {
  return doSomethingTestable(globalList);
}

function doSomethingTestable(list) {
  ...
}

Abbiamo quindi introdotto una seam in un progetto in cui possiamo inserire dati di test e rivedere i risultati.

Mantenendo invariata la vecchia funzione (come wrapper attorno alla nuova funzione testabile), non è necessario aggiornare immediatamente i dipendenti di questa funzione. Quindi questo refactoring è limitato a quella funzione ed è quindi a basso rischio. In futuro (quando avremo migliori test unitari), possiamo cambiare le altre parti per utilizzare la funzione parametrizzata. Alla fine, il codice è ridotto a:

function doSomethingTestable(list) {
  ...
}

(Una nota sulla denominazione: la vecchia funzione e la nuova funzione essenzialmente vogliono lo stesso nome. In realtà non raccomando un ...Testable o ...improved suffisso per disambiguarli! A volte questo può essere risolto non aggiungendo un'altra funzione, e solo un parametro con un valore predefinito.A volte il nome originale era cattivo, e questa è una buona opportunità per rinominare. abbiamo trovato il modo migliore per descrivere il parametro extra, ad esempio sendMessage() potrebbe diventare sendMessageToQueue(queue) .)

Invece di passare i dati nudi come parametro, è spesso meglio considerare quale tipo di operazioni vengono eseguite su questi dati e incapsulare tali operazioni. Dovremmo quindi passare un oggetto, dove i metodi su questo oggetto documentano alcune intenzioni del nostro codice. Ad esempio, potremmo non aver bisogno di tutte le operazioni per un elenco (come l'indicizzazione e l'iterazione) e vogliamo solo push() e pop() elementi.

Offrire un insieme limitato di metodi con nomi auto-documentanti tende a rendere il codice più ovvio e solido. Rende inoltre più semplice il test del codice, poiché non è necessario convalidare uno stato di risultato specifico e invece è possibile convalidare le azioni di quel codice. (Anche se spesso convalidare lo stato completo dell'output è ancora la soluzione più semplice.)

    
risposta data 03.05.2018 - 20:54
fonte

Leggi altre domande sui tag