Ho problemi con l'utilizzo del giusto flusso di lavoro con TDD. Alcuni dicono che dovremmo progettare prima di scrivere qualsiasi codice, alcuni dicono che dovremmo fare un test, farlo passare, quindi rifattorizzare il codice e questo dovrebbe aiutare il nostro pensiero a trovare il progetto giusto.
Ma tutti affermano che dovresti avere 10 volte più test unitari rispetto ai test di integrazione.
Mi sento a mio agio iniziando facendo un test di integrazione che farebbe tutta la user story, e quindi il refactoring. Ma alla fine ho quasi solo test di integrazione e quasi nessun test unitario.
Ecco un esempio del flusso di lavoro che utilizzo:
Caratteristica: un utente deve essere in grado di registrarsi tramite l'API in / register /, passando l'email e una password.
Prima farei un test di integrazione:
<?php
class RegisterUserTest extends TestCase
{
/** @test */
public function user_is_registered_when_email_is_valid()
{
$email = '[email protected]';
// Given the email was not registered before
$this->notSeeInDatabase('user', ['email' => $email]);
// When we post a request to /register/
$this->json('POST', '/register/', ['email' => $email]);
// Then we see the user is now registered
$this->seeInDatabase('user', ['email' => $email]);
}
}
Quindi scriverei il codice per fare passare questo test (mostrerò solo il codice del controller):
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\User;
class RegisterController extends Controller
{
public function registerUser(Request $request)
{
(new User)->create(['email' => $request->input('email')]);
}
}
Ora basta fare il primo test, quindi mi fermo qui e faccio un altro test per dimostrare che quando l'e-mail non è valida non dovrebbe essere inserita nel database, e dovrebbe restituire un codice di risposta 422:
<?php
class RegisterUserTest extends TestCase
{
//...
/** @test */
public function invalid_email_returns_a_422_and_user_is_not_registered()
{
// Given the email is invalid
$email = 'invalid';
// When we post a request to /register/
$this->json('POST', '/register/', ['email' => $email]);
// Then we see the response code is 422
$this->assertResponseStatus(422);
$this->notSeeInDatabase('user', ['email' => $email]);
}
}
Ora scriverò il codice per farlo passare:
public function registerUser(Request $request)
{
$email = $request->input('email');
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
return response('Invalid Email', 422);
}
(new User)->create(['email' => $email]);
}
Ora per me è già troppa logica nel controller, quindi dovrei fare il refactoring ovviamente:
public function registerUser(Request $request)
{
try {
$user = new User;
$user->setEmail($request->input('email'));
$user->save();
} catch (InvalidArgumentException $invalidArgumentException) {
return response($invalidArgumentException->getMessage(), 422);
}
}
Hai un'idea. Non dovevo fare test di unità lì, i miei test di integrazione funzionano bene e sono sufficienti. Potrei andare avanti senza test necessari dell'unità.
Quindi come / quando inizi il test unitario?