PC_MAGAS Δημοσ. 25 Απριλίου 2019 Δημοσ. 25 Απριλίου 2019 Καλησπέρες, Όπως ερωτώ και στο stackoverflow έχω μια κλάση στην οποία έχω μια μέθοδο getToken η οποία εκκινεί ένα Session: namespace PCMagas; define("API_OAUTH_TOKEN_URL","https://api.dropboxapi.com/oauth2/token"); use \GuzzleHttp\Client; use \GuzzleHttp\RequestOptions; class Dropbox { /** * @param String $appid The Dropbox Application Id. * @param String $secret The dropbox Secret * @param Client $httpClient The interface used to consume the Dropbox Rest API */ public function __construct($appId,$secret,Client $httpClient) { $this->appId=$appId; $this->secret=$secret; $this->httpClient=$httpClient; } /** * Common Logic for Handling Http Error * @param Integer $code * @throws Exception */ private function httpErrorHandling($code) { switch($code){ case 400: throw new Exception('Invalid HttpRequest to DropBoxApi'); case 401: throw new Exception('Invalid Dropbox Token'); case 403: throw new Exception('Access Denied'); case 429: throw new Exception('Try again later (after a 10th cup of coffee)'); case 409: throw new Exception('Api user provided error'); //Treat all 500 error code (seems kinda ugly) case 500: case 501: case 502: case 503: case 504: case 505: case 506: case 507: case 508: case 510: case 511: throw new Exception('Internal Dropbox Error'); } } /** * @param String $code * @return String * @throws InvalidArgumentException In case that the code is not correctly Provided. * @throws Exception if any error occured when token cannot be fetched */ public function getToken($code) { //If code get token from code //Else get token from $session //Not satisfiable thows Esception session_start(); if(!empty($_SESSION['token'])){ return $_SESSION['token']; } if(empty($code)){ throw new \InvalidArgumentException('Please provide a code fetched from Dropbox Athorization.'); } if(empty($_SESSION['redirect_url'])){ throw new \Exception('Cannot find the url that Dropbox Redirected From'); } $response = $this->httpClient->request("POST",API_OAUTH_TOKEN_URL,[ RequestOptions::FORM_PARAMS =>[ 'code'=>$code, 'grant_type'=>'authorization_code', 'redirect_uri'=>$_SESSION['redirect_url'] ], RequestOptions::AUTH=>[$this->appId,$this->secret] ]); //Call method and let it blow up $this->httpErrorHandling($response->getStatusCode()); $body=$response->getBody()->getContents(); $body=json_decode($body,true); $_SESSION['token']=$body['access_token']; return $_SESSION['token']; } } Και προσπαθώ να την κάνω Unit test: namespace PCMagas\Tests; use PHPUnit\Framework\TestCase; use GuzzleHttp\Handler\MockHandler; use GuzzleHttp\HandlerStack; use GuzzleHttp\Psr7\Response; use GuzzleHttp\Psr7\Request; use GuzzleHttp\Client; use PCMagas\Dropbox; define('ERROR_CODES',[400,401,403,409,429,500,501,502,503,504,505,506,507,508,510,511]); define('ERROR_CODE_LENGTH',count(ERROR_CODES)); final class DropBoxTest extends TestCase { private function mockErrorGuzzle() { $responses=array_map(function($statusCode){ return new Response($statusCode); },ERROR_CODES); $handler = new MockHandler($responses); $client = new Client(['handler'=>$handler]); return $client; } public function testHttpErrorOnTonenFetch() { $guzzle=$this->mockErrorGuzzle(); $dropBox=new Dropbox("dummyappId","dummySecret",$guzzle); for($i=0;$i<ERROR_CODE_LENGTH;$i++) { $this->expectException(\Exception::class); $dropBox->getToken("dummyCode"); } } } Όμως όταν πάω να εκτελέσω το unit test λαμβάνω το εξής σφάλμα: There was 1 error: 1) PCMagas\Tests\DropBoxTest::testHttpErrorOnTonenFetch session_start(): Cannot start session when headers already sent /home/vagrant/code/src/PCMagas/Dropbox.php:84 /home/vagrant/code/tests/DropBoxTest.php:36 ERRORS! Tests: 1, Assertions: 0, Errors: 1. Μπορείτε να με βοηθήσετε στο πως να διαχειριστώ το σφάλμα αυτό;
k33theod Δημοσ. 25 Απριλίου 2019 Δημοσ. 25 Απριλίου 2019 Μάλλον παίζει ρόλο το παρακάτω https://www.php.net/manual/en/function.session-start.php Note: To use cookie-based sessions, session_start() must be called before outputing anything to the browser. Βγάλε το session_start() έξω από την κλάση και βάλτο κάτω από το <?php
PC_MAGAS Δημοσ. 25 Απριλίου 2019 Μέλος Δημοσ. 25 Απριλίου 2019 Ναι όμως θα εκκινώ το session είτε καλώ την μέθοδο είτε όχι, πράγμα που δεν θέλω. Οι κλάσεις φορτώνονται με PSR-4 autoloading και ο php κώδικας δεν τρέχει εντός borwser.
k33theod Δημοσ. 26 Απριλίου 2019 Δημοσ. 26 Απριλίου 2019 13 ώρες πριν, PC_MAGAS είπε Ναι όμως θα εκκινώ το session είτε καλώ την μέθοδο είτε όχι, πράγμα που δεν θέλω. Οι κλάσεις φορτώνονται με PSR-4 autoloading και ο php κώδικας δεν τρέχει εντός borwser. Δεν ξέρω άλλη λύση εναλλακτικά μπορείς να βάλεις στις ρυθμίσεις το session_auto_start.
PC_MAGAS Δημοσ. 26 Απριλίου 2019 Μέλος Δημοσ. 26 Απριλίου 2019 (επεξεργασμένο) Σκεύτικα εάν έκανα μια Adapter κλάση για το Session θα μπορούσα εύκολα να την κάνω mock, αλλά μετά πως τεστάρεις την κλάση αυτή; Τελικά κατέληξα στο να κάνω adapt το Session σε μια δική μου κλάση όπως αναφέρω στο https://stackoverflow.com/a/55871054/4706711, το κακό είναι ότι για να τεσταριστεί ο Adapter σε όλες τις περιπτώσεις θέλει 3 κιλά κώδικα και internal webserber. Το καλό είναι ότι έχεις ελάχιστο Κώδικα μη-τεσταρισμένο (Τον Adapter του Session) και τεσταρισμένο logic (την λογική του Πάρε-δώσε με το Dropbox). Άντε τώρα καλό Mutation Testing. Επεξ/σία 26 Απριλίου 2019 από PC_MAGAS
Προτεινόμενες αναρτήσεις
Δημιουργήστε ένα λογαριασμό ή συνδεθείτε για να σχολιάσετε
Πρέπει να είστε μέλος για να αφήσετε σχόλιο
Δημιουργία λογαριασμού
Εγγραφείτε με νέο λογαριασμό στην κοινότητα μας. Είναι πανεύκολο!
Δημιουργία νέου λογαριασμούΣύνδεση
Έχετε ήδη λογαριασμό; Συνδεθείτε εδώ.
Συνδεθείτε τώρα