Aproximadamente. tradutor: a regra em si é bastante antiga, e o exemplo dado no artigo é, em minha opinião, o mais simples. Portanto, o artigo é mais adequado para iniciantes, pessoas com boa experiência em escrever autotestes podem não encontrar nada de novo para si mesmas. UPD. Eu ainda não acho que o autor propõe envolver todas as APIs do framework com o qual você está trabalhando com sua própria camada (bem, seria extremamente estranho), mas sim sobre classes de uso geral mal estruturadas / tipadas, como HttpRequest do exemplo do artigo.
Os aplicativos da Web geralmente são projetados para lidar com solicitações HTTP. Os objetos são comumente usados para encapsular dados de solicitação. Dependendo da estrutura, podemos ter uma interface como
interface HttpRequest
{
public function get(string $name): string;
// ...
}
ou mesmo uma aula específica como
class HttpRequest
{
public function get(string $name): string
{
// ...
}
// ...
}
que podemos (e devemos) usar para acessar os dados da solicitação.
Symfony, por exemplo, possui Symfony \ Component \ HttpFoundation \ Request :: get (). Por exemplo, não vamos nos preocupar com o tipo de solicitação HTTP que estamos tratando (GET, POST ou outro). Em vez disso, vamos nos concentrar em APIs implícitas como HttpRequest :: get () e nos problemas que elas representam.
, , , 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 .
Obviamente, você terá que tornar seu wrapper de solicitação específico para cada controlador. Seu código precisa de cabeçalhos específicos? Crie um método apenas para obtê-los. Seu código precisa de um arquivo carregado? Crie um método para obter exatamente isso.
Uma solicitação HTTP completa pode conter cabeçalhos, valores, talvez arquivos carregados, corpo POST, etc. Configurar um stub de teste ou simulação para tudo isso enquanto você não possui a interface impede que você conclua o trabalho. Definir sua própria interface simplifica muito a tarefa.