Ca. Übersetzer: Die Regel selbst ist ziemlich alt, und das Beispiel im Artikel ist meiner Meinung nach das einfachste. Daher ist der Artikel eher für Anfänger geeignet. Personen mit guten Erfahrungen beim Schreiben von Autotests finden möglicherweise nichts Neues für sich. UPD. Ich denke immer noch nicht, dass der Autor vorschlägt, alle APIs des Frameworks, mit dem Sie arbeiten, mit seiner eigenen Ebene zu verpacken (nun, es wäre äußerst seltsam), sondern es geht um lose strukturierte / typisierte Allzweckklassen. wie HttpRequest aus dem Beispiel im Artikel.
Webanwendungen sind häufig für die Verarbeitung von HTTP-Anforderungen ausgelegt. Objekte werden üblicherweise zum Einkapseln von Anforderungsdaten verwendet. Abhängig vom Framework haben wir möglicherweise eine Schnittstelle wie
interface HttpRequest
{
public function get(string $name): string;
// ...
}
oder sogar eine bestimmte Klasse wie
class HttpRequest
{
public function get(string $name): string
{
// ...
}
// ...
}
mit denen wir auf die Anforderungsdaten zugreifen können (und sollten).
Symfony hat beispielsweise Symfony \ Component \ HttpFoundation \ Request :: get (). Zum Beispiel werden wir uns keine Gedanken darüber machen, welche Art von HTTP-Anfrage wir bearbeiten (GET, POST oder andere). Konzentrieren wir uns stattdessen auf implizite APIs wie HttpRequest :: get () und die damit verbundenen Probleme.
, , , get() , . . get():
class SomeController
{
public function execute(HttpRequest $request): HttpResponse
{
$id = $request->get('id');
$amount = $request->get('amount');
$price = $request->get('price');
// ...
}
}
, action- (: (eng )). , HTTP-.
HttpRequest (stub) mock- SomeController , get() , : 'id', 'amount' 'price'.
, , action- .
SomeController HttpRequest (stub) unit PHPUnit :
$request = $this->createStub(HttpRequest::class);
$request->method('get')
->willReturnOnConsecutiveCalls(
'1',
'2',
'3',
);
$controller = new SomeController;
$controller->execute($request);
SomeController HttpRequest, mock-, :
$request = $this->createMock(HttpRequest::class);
$request->expects($this->exactly(3))
->method('get')
->withConsecutive(
['id'],
['amount'],
['price']
)
->willReturnOnConsecutiveCalls(
'1',
'2',
'3',
);
$controller = new SomeController;
$controller->execute($request);
, HttpRequest::get() : «id», «amount» , , «price».
SomeController::execute(), HttpRequest::get(), . , . .
, HTTP-, API, , HTTP, get(). , , , : HttpRequest , .
« , » « , ». 2009 « - »:
« , , , , , . , , , , , ».
, , ? :
« [...] , , - , , . [...], - API [...] "
:
interface SomeRequestInterface
{
public function getId(): string;
public function getAmount(): string;
public function getPrice(): string;
}
, , value-. .
SomeRequestInterface :
$request = $this->createStub(SomeRequestInterface::class);
$request->method('getId')
->willReturn(1);
$request->method('getAmount')
->willReturn(2);
$request->method('getPrice')
->willReturn(3);
, HTTP- , - HTTP- . . HTTP- . . :
class SomeRequest implements SomeRequestInterface
{
private HttpRequest $request;
public function __construct(HttpRequest $request)
{
$this->request = $request;
}
public function getId(): string
{
return $this->request->get('id');
}
public function getAmount(): string
{
return $this->request->get('amount');
}
public function getPrice(): string
{
return $this->request->get('price');
}
}
:
class SomeController
{
public function execute(HttpRequest $request)
{
return $this->executable->execute(
new SomeRequest($request)
)
}
}
SomeController , , HTTP .
Natürlich müssen Sie Ihren Request Wrapper für jeden Controller spezifisch machen. Benötigt Ihr Code bestimmte Header? Erstellen Sie eine Methode, um sie nur zu erhalten. Benötigt Ihr Code eine hochgeladene Datei? Erstellen Sie eine Methode, um genau dies zu erhalten.
Eine vollständige HTTP-Anforderung kann Header, Werte, möglicherweise hochgeladene Dateien, POST-Text usw. enthalten. Wenn Sie einen Teststub oder ein Mock für all dies einrichten, während Sie die Schnittstelle nicht besitzen, können Sie den Job nicht erledigen. Das Definieren Ihrer eigenen Schnittstelle vereinfacht die Aufgabe erheblich.