2014-10-24 17 views
6

Próbuję przetestować moją implementację programu obsługi Stripe webhook. Dane paskiem webhook przychodzi po drugiej stronie drutu jako surowego JSON w treści żądania POST, więc przechwytywania i dekodowania danych jako takie:Czy mogę użyć metody "call" Laravel do wysyłania surowych danych JSON w teście jednostkowym?

public function store() 
{ 
    $input = @file_get_contents("php://input"); 
    $request = json_decode($input); 
    return Json::encode($request); 
} 

I 'm próby badanej jednostki tego kodu, ale nie mogę dowiedzieć się, jak wysłać surowe dane JSON w jednostce testowej, tak, że mogę ją odzyskać przy pomocy funkcji file_get_contents("php:input//"). To co próbowałem (używając PHPUnit):

protected $testRoute = 'api/stripe/webhook'; 

protected $validWebhookJson = <<<EOT 
{ 
    "id": "ch_14qE2r49NugaZ1RWEgerzmUI", 
    "object": "charge", 
    // and a bunch of other fields too 
} 
EOT; 

public function testWebhookDecdoesJsonIntoObject() 
{ 
    $response = $this->call('POST', $this->testRoute, $this->validWebhookJson); // fails because `$parameters` must be an array 
    $response = $this->call('POST', $this->testRoute, [], [], ['CONTENT_TYPE' => 'application/json'], $this->validWebhookJson); 
    dd($response->getData(true)); // array(0) {} BOOOO!!! Where for to my data go? 
} 

Próbowałem zostały również curl ale która stałaby żądania zewnętrznego, który nie ma sensu dla mnie z perspektywy jednostkowej testowania. Jak mogę zasymulować żądanie POST z surowymi danymi JSON w treści, które zostaną odebrane przez moją metodę store?

+0

Technika drugiej rozmowy wygląda mi na poprawną. Przypuszczam, że "pęczek innych pól" jest niepoprawnie sformatowany, a więc json, który w zasadzie echo jest, jest pusty. Z pewnością końcowy przecinek w obciętym przykładzie nie jest prawidłowy json. Zacznę od xdebugging store(). – scipilot

Odpowiedz

0

Z Laravel 5.1 łatwo jest wysłać JSON, wystarczy podać zwykłą tablicę PHP, która zostanie automatycznie zakodowana. Przykład z docs:

$this->post('/user', ['name' => 'Sally']) 
     ->seeJson([ 
      'created' => true, 
     ]); 

Od docs: http://laravel.com/docs/5.1/testing#testing-json-apis

+0

Nie myśl, że to prawda. Dokumenty faktycznie mówią, że tablica przekazana do 'seeJson()' zostanie automatycznie przeanalizowana, a nie tablica dla pola parametrów. Podobny problem pojawił się w Lumen's (w zasadzie Laravel) zagadnieniach github [tutaj] (https://github.com/laravel/lumen-framework/issues/149) i regularnym współpracownikiem do laravel stwierdza, że ​​musisz zakodować to ręcznie. – kidshenlong

4

Można. Ale musisz wysłać zakodowany JSON jako treść (aka ciała żądania), a nie parametr.

$this->call(
    'POST', 
    '/articles', 
    [], 
    [], 
    [], 
    $headers = [ 
     'HTTP_CONTENT_LENGTH' => mb_strlen($payload, '8bit'),  
     'CONTENT_TYPE' => 'application/json', 
     'HTTP_ACCEPT' => 'application/json' 
    ], 
    $json = json_encode(['foo' => 'bar']) 
); 

To jest 7 parametr.

Jeśli spojrzysz na definicję metody (w rdzeniu Laravel), powinieneś być w stanie zobaczyć, czego oczekuje.

public function call($method, $uri, $parameters = [], $cookies = [], $files = [], $server = [], $content = null) 

ta obecnie nie jest obsługiwany jeszcze przez laravel 5.1 poście, patch, umieścić, usuwanie Metody wygodę choć.

Ten dodatek jest obecnie przedmiotem dyskusji here i here.

EDYCJA: Powinienem oświadczyć, że ta odpowiedź jest oparta na instalacji Laravel 5.1, więc może nie być w 100% stosowana, jeśli masz starszą wersję.

+0

To wciąż ma zastosowanie do Laravel 5.4; jednak nagłówek musi mieć wartość "CONTENT_TYPE", a nie "HTTP_CONTENT_TYPE". Zauważ, że wszystkie inne nagłówki (w tym autoryzacja i co nie) muszą rozpoczynać się od 'HTTP_'. – Alex

3

Można użyć metody json opisany tutaj:

https://laravel.com/api/5.1/Illuminate/Foundation/Testing/TestCase.html#method_json

jak widać trzeci parametr jest tablicą czarownica danych w tej sprawie zostaną przekazane do organu wniosku jako JSON, i jeśli potrzebujesz przekazać dodatkowe nagłówki, możesz je przekazać jako tablicę w czwartym parametrze.

Przykład: (Wewnątrz klasy testowej)

public function testRequestWithJSONBody() 
{ 
    $this->json(
      'POST', //Method 
      '/', //Route 
      ['key1' => 'value1', 'key2' => 'value2'], //JSON Body request 
      ['headerKey1' => 'headerValue1','headerKey2' => 'headerValue2'] // Extra headers (optional) 
     )->seeStatusCode(200); 
} 

Nadzieja to pomaga innym.

+0

Nie można przekazać nieprzetworzonego łańcucha JSON przy użyciu tego podejścia, a jedynie tablicę. – Alex

0

Można zastąpić metodę pocztowy w CrawlerTrait: https://laravel.com/api/5.1/Illuminate/Foundation/Testing/CrawlerTrait.html

Albo utworzyć nową metodę pomocnika jak poniżej, który przyjmuje jeden dodatkowy opcjonalny argument: rawContent

public function postRawContent($uri, array $data = [], array $headers = [], $rawContent = null) 
{ 
    $server = $this->transformHeadersToServerVars($headers); 

    $this->call('POST', $uri, $data, [], [], $server, $rawContent); 

    return $this; 
} 
0

chciałem przetestować JSON jest wysłana z przeglądarki do zaplecza. Chciałem umieścić surowy json w phpunit, więc nie musiałem przekodować tablicy, która wprowadziła błędy.

Aby to zrobić po raz pierwszy przekształcony obiekt json do ciągu w javascript (przeglądarki lub klient) i wrzucili go do dziennika:

console.log(JSON.stringify(post_data)) 

Następny mogę kopiować i wklejać, że w teście phpunit, następnie dekodowany go do tablicy. Potem po prostu wysłał tę tablicę do json:

$rawContent = '{"search_fields":{"vendor_table_id":"123","vendor_table_name":"","vendor_table_account_number":"","vendor_table_active":"null"},"table_name":"vendor_table"}'; 

$this->json('POST', '/vendors', json_decode($rawContent, true)) 
    ->seeJson([ 
      'id' => 123, 
     ]); 

To był jedyny sposób, że pracował dla mnie po wdrożeniu innych odpowiedzi do tego wpisu, więc pomyślałem, że podzielę. Używam laravel 5.

Powiązane problemy