Funzioni di test delle unità senza logica aziendale (solo controlli) [duplicato]

1

Il mio team sta cercando di trovare il modo migliore per testare uno dei nostri componenti; lo scopo principale è verificare se l'utente / attore ha il diritto di completare l'operazione richiesta. Il componente è formato da molte funzioni che di solito hanno la seguente struttura (semplificata): Lingua di esempio: PHP

public function addGroup($idEntity, $nameGroup){
if (!$this->logic->isEntityActive($idEntity)){
    throw new EntityNotActiveException();
}
if ($idEntity != $this->getServiceLocator()->get('request')->getQuery()->get('idEntity')){
    throw new NoRightsException();
}
if ($this->logic->isGroupWithNameAlreadyInDB($idEntity, $nameGroup)){
    throw new GroupAlreadyExistException();
}
return $this->logic->addGroupToEntity($idEntity, $nameGroup);
}

Come puoi vedere questo metodo non ha "logica" di per sé (a parte i controlli) e alla fine inoltra semplicemente la richiesta alla logica sottostante. Siamo in conflitto su come testare correttamente questa funzione. Prendiamo in giro tutto? Possiamo farlo e in ogni prova falsificare alcuni "fallimenti", ma il problema rimane che per testare la correttezza della funzione si prende in giro tutto. Ogni singola funzione In tal caso non stai testando nulla. Potremmo davvero usare qualche consiglio su questo problema. Qualcuno può mostrarci esempi di un buon modo per testare una funzione come questa?

Usiamo phpunit. Grazie in anticipo per il tuo aiuto.

    
posta Jecnua 28.03.2013 - 17:53
fonte

3 risposte

3

La mia opinione è che ti prendi in giro tutto. Stai facendo in modo che i controlli funzionino correttamente, non la logica sottostante nella chiamata alla funzione che restituisce il vero / falso). Mettere a punto questo rimuove anche la comprensione della logica dietro le chiamate di funzione in ciascuna delle condizioni. E questo test non fallirà se / quando cambierà la logica che diventerebbe un incubo di manutenzione.

Il problema principale è in questa riga:

if ($idEntity != $this->getServiceLocator()->get('request')->getQuery()->get('idEntity'))

Quando finisci con un finto, restituisci una finta. Questo è un codice olfattivo e viola il D in SOLID ( link ). Prenderò in considerazione la possibilità di refactoring in modo da passare il risultato di getQuery() .

Probabilmente finirei a scrivere test separati per le eccezioni e uno per il successo. Come i mazzi di ciascuno finirebbero per aspettarsi chiamate diverse.

Modifica Tenere presente che i test aiutano a fornire informazioni sul comportamento previsto del codice e anche per assicurarsi che eventuali modifiche nella logica non interrompano la funzionalità esistente. Se desideri modificare le condizioni di addGroup , puoi assicurarti di aver mantenuto le funzionalità esistenti senza dover scavare nelle chiamate alla funzione sottostante.

Ecco come sarà il test delle eccezioni (usando PHPUnit):

/**
 * @dataProvider dataExceptions
 */
public function testAddGroupExceptions($isActive, $inGroup, $id, $exception) {
    $this->expectsException($exception);

    $logic = $this->getMockBuilder('logic')->setMethods(array('isEntityActive', 'isAlreadyInGroup', 'addGroupToEntity'))->getMock();

    //Set number of calls to any to not tie to order in function
    $logic->expects($this->any())->method('isEntityActive')->will($this->returnValue($isActive));
    $logic->expects($this->any())->method('isAlreadyInGroup')->will($this->returnValue($isActive));        

    //This is a fail case, so do not add group
    $logic->expects($this->never())->method('addGrouptToEntity');

    //Not doing all the mocks to get the 'idEntity'
    $query = $this->getMockBuilder('query')->setMethods(array('get'))->getMock();

    $query->expects($this->any())->method('get')->with('idEntity')->will($this->returnValue($id));

    $idEntity = 'test';
    $group = 'foo';

    //Instantiate the object - $test
    $test->addGroup($idEnity, $group);
}
    
risposta data 28.03.2013 - 18:33
fonte
2

Non c'è unità di punto che test qualcosa di banale. Ci deve essere un po 'di logica per avere un valore per un test unitario.

In questo caso potrebbe valere la pena di coprirlo indirettamente con i tuoi più ampi test di integrazione.

    
risposta data 28.03.2013 - 18:33
fonte
1

Non testare le funzioni banali come le proprietà senza logica di validazione. I test di integrazione dovrebbero coprire adeguatamente tali metodi.

    
risposta data 28.03.2013 - 18:33
fonte

Leggi altre domande sui tag