Testovanie
GooglePlaces::fake() nahradí živého klienta zaznamenávajúcim GooglePlacesFake a vráti ho — bez Http::fake() a bez živých (platených) volaní. Nič sa nedostane ku Google: každé volanie sa zaznamená a odpoveď pochádza z toho, čo ste pripravili metódami with*():
use RoundlyConsulting\GooglePlaces\DataTransferObjects\AutocompletePrediction;
use RoundlyConsulting\GooglePlaces\DataTransferObjects\AutocompleteQuery;
use RoundlyConsulting\GooglePlaces\DataTransferObjects\Place;
use RoundlyConsulting\GooglePlaces\Facades\GooglePlaces;
$fake = GooglePlaces::fake();
$fake->withAutocomplete([new AutocompletePrediction('Café Roma', 'p1', ['cafe'])]);
$fake->withDetails(new Place('Café Roma'));
// ...exercise code that calls the facade...
$fake->assertAutocompleted(fn (AutocompleteQuery $q) => $q->input === 'Café');
$fake->assertDetailsRequested('p1');
$fake->assertNothingGeocoded();Fake je PlacesClient nasadený za fasádu aj za väzbu v kontajneri, takže ho zasiahnu klienti vložení cez konštruktor, session(), matrix(), photo() (vrátane save(), ktorý zapíše pripravené bajty), stránkované vyhľadávanie, príkaz google-places:check aj geolokačný driver google_places.
Príprava výsledkov
| Príprava | Pre metódy | Ak nie je pripravené |
|---|---|---|
withAutocomplete(array $predictions) | autocomplete() | Prázdna kolekcia. |
withDetails(?Place $place) | details() | null. |
withGeocode(array $results) | geocode() | Prázdna kolekcia. |
withGeocodeAddress(array $results) | geocodeAddress() | Prázdna kolekcia. |
withTextSearch(array $places) | textSearch(), textSearchPaginated() | Prázdne; paginátor vráti jednu stránku. |
withNearbySearch(array $places) | nearbySearch(), nearbySearchPaginated() | Prázdne; paginátor vráti jednu stránku. |
withFindPlace(?Place $place) | findPlace() | null. |
withDistance(Distance|MultipleDistances $distance) | distance() | Nulová Distance. |
withMatrix(DistanceMatrix $matrix) | computeMatrix(), matrix()->…() | Prázdna matica s rozmermi podľa dopytu. |
withPhoto(string $bytes, ?string $uri = null) | photoContents(), photoUri(), photo()->… | Prázdne bajty; falošná URL bez kľúča zostavená z názvu fotografie. |
withPhotoUrl(string $url) | photoUrl() | URL média zostavená z názvu fotografie. |
withCheck(array $results) | check(), google-places:check | Tri zdravé výsledky. |
Asercie
Každé volanie sa zaznamená ako jeho query objekt — skalárne hodnoty sa najprv prevedú na príslušnú triedu dopytu. Asercia bez callbacku prejde, ak k volaniu vôbec došlo; s callbackom musí zodpovedať aspoň jeden zaznamenaný dopyt:
| Asercia | Prejde, keď |
|---|---|
assertAutocompleted(fn (AutocompleteQuery $q) => $q->input === 'Café') | Volanie autocomplete (zodpovedajúce callbacku). |
assertDetailsRequested('p1') | Volanie details; reťazec porovná place id, callback dostane DetailsQuery. |
assertGeocoded(fn (ReverseGeocodingQuery $q) => $q->location->latitude === 48.1486) | Spätné geokódovanie. |
assertAddressGeocoded('Hlavné námestie 1, Bratislava') | Priame geokódovanie; reťazec porovná adresu. |
assertTextSearched(fn (TextSearchQuery $q) => $q->textQuery === 'pizza') | Textové vyhľadávanie, vrátane stránkovaného. |
assertNearbySearched(fn (NearbySearchQuery $q) => $q->radius === 1500) | Okolité vyhľadávanie, vrátane stránkovaného. |
assertFindPlaceRequested(fn (string $text) => $text === 'Eiffel Tower') | Volanie findPlace() — callback dostane len hľadaný text, nie preferovanú polohu. |
assertDistanceRequested(fn (DistanceQuery $q) => $q->type === TravelMode::Driving) | Volanie distance(). |
assertMatrixComputed(fn (MatrixQuery $q) => count($q->origins) === 2) | Matica, cez computeMatrix() alebo matrix()->…(). |
assertPhotoRequested('places/p1/photos/a') | Bajty alebo URL fotografie bez kľúča; callback dostane PhotoQuery (contents je pri URL false). |
assertChecked() | Prebehol check() — priamo alebo cez google-places:check. |
assertNothingAutocompleted() | Žiadne volanie autocomplete. |
assertNothingGeocoded() | Žiadne spätné geokódovanie. |
assertNothingRequested() | Žiadne volanie, okrem photoUrl() a vytvorenia handles. |
Samotné session(), matrix() a photo() sa nezaznamenávajú — zaznamenajú sa volania, ktoré handles vykonajú. Volania v session sa zapíšu ako bežné autocomplete a details s tokenom session v dopyte, overujte preto $q->sessionToken. Fake nikdy nevyhodí výnimku.
Zostavenie falošných výsledkov
Výsledky sú obyčajné DTO, takže ich zostavíte priamo:
use RoundlyConsulting\GooglePlaces\DataTransferObjects\Distance;
use RoundlyConsulting\GooglePlaces\DataTransferObjects\DistanceQuery;
use RoundlyConsulting\GooglePlaces\DataTransferObjects\Geometry;
use RoundlyConsulting\GooglePlaces\DataTransferObjects\Location;
use RoundlyConsulting\GooglePlaces\DataTransferObjects\ReverseGeocodingResult;
use RoundlyConsulting\GooglePlaces\Enums\TravelMode;
use RoundlyConsulting\GooglePlaces\Facades\GooglePlaces;
it('quotes a delivery time for a typed address', function () {
$fake = GooglePlaces::fake();
$point = new Location(48.1435, 17.1089);
$fake->withGeocodeAddress([
new ReverseGeocodingResult(
address: 'Hlavné námestie 1, 811 01 Bratislava, Slovakia',
placeId: 'p1',
geometry: new Geometry($point, $point, $point),
types: ['street_address'],
),
]);
$fake->withDistance(new Distance('4.2 km', 4200, '12m', 720, TravelMode::Driving));
// ...call the code under test...
$fake->assertAddressGeocoded('Hlavné námestie 1, Bratislava');
$fake->assertDistanceRequested(fn (DistanceQuery $q) => $q->type === TravelMode::Driving);
$fake->assertNothingAutocompleted();
});Kontrola, že sa nevolalo
use RoundlyConsulting\GooglePlaces\DataTransferObjects\Place;
use RoundlyConsulting\GooglePlaces\DataTransferObjects\TextSearchQuery;
use RoundlyConsulting\GooglePlaces\Facades\GooglePlaces;
it('renders the cached page without calling Google', function () {
$fake = GooglePlaces::fake();
$this->get('/places/cached')->assertOk();
$fake->assertNothingRequested(); // no lookup, photo request or check at all
});
it('searches by text and never geocodes', function () {
$fake = GooglePlaces::fake()->withTextSearch([new Place('Pizza Roma')]);
$this->get('/search?q=pizza')->assertOk();
$fake->assertTextSearched(fn (TextSearchQuery $q) => $q->textQuery === 'pizza');
$fake->assertNothingAutocompleted();
$fake->assertNothingGeocoded();
});Fotografie
Bajty pripravte cez withPhoto() a fake skombinujte so Storage::fake():
use Illuminate\Support\Facades\Storage;
use RoundlyConsulting\GooglePlaces\DataTransferObjects\PhotoQuery;
use RoundlyConsulting\GooglePlaces\Facades\GooglePlaces;
it('stores the hero photo', function () {
Storage::fake('public');
$fake = GooglePlaces::fake()->withPhoto('JPEG-BYTES');
GooglePlaces::photo('places/p1/photos/a', 1200, 800)->save('public', 'p1.jpg');
Storage::disk('public')->assertExists('p1.jpg');
$fake->assertPhotoRequested(fn (PhotoQuery $q) => $q->name === 'places/p1/photos/a' && $q->maxWidth === 1200);
});Kontrola stavu API
use RoundlyConsulting\GooglePlaces\DataTransferObjects\ApiCheckResult;
use RoundlyConsulting\GooglePlaces\Facades\GooglePlaces;
config(['google-places.key' => 'test-key']); // the command refuses to run without a key
$fake = GooglePlaces::fake()->withCheck([
new ApiCheckResult('Places API (New)', true, 'Reachable and authorized.'),
new ApiCheckResult('Routes API', false, 'Unreachable: timeout'),
new ApiCheckResult('Geocoding API', true, 'Reachable and authorized.'),
]);
$this->artisan('google-places:check')->assertFailed();
$fake->assertChecked();Testovanie so skutočným klientom
Ak chcete otestovať zostavenie požiadavky, klasifikáciu chýb, cache či rate limiting, ponechajte skutočného klienta a nahraďte radšej HTTP vrstvu:
use Illuminate\Support\Facades\Http;
use RoundlyConsulting\GooglePlaces\Exceptions\PlacesException;
use RoundlyConsulting\GooglePlaces\Facades\GooglePlaces;
config(['google-places.key' => 'test-key', 'google-places.rate_limits.places.enabled' => false]);
Http::fake([
'places.googleapis.com/v1/places:searchText' => Http::response([
'error' => [
'status' => 'INVALID_ARGUMENT',
'message' => 'API key not valid.',
'details' => [['@type' => 'type.googleapis.com/google.rpc.ErrorInfo', 'reason' => 'API_KEY_INVALID']],
],
], 400),
]);
try {
GooglePlaces::textSearch('coffee');
} catch (PlacesException $e) {
expect($e->isDenied())->toBeTrue()
->and($e->isInvalidRequest())->toBeFalse()
->and($e->googleReason())->toBe('API_KEY_INVALID');
}Vlastnú testovaciu sadu balíka spustíte v jeho repozitári:
composer testPrejavte lásku k open source
Tento balík je zadarmo pod licenciou MIT. Ak vám šetrí čas, jednorazový príspevok alebo členstvo na Patreone nám pomôže ho ďalej udržiavať, testovať a dokumentovať.
Ďalšie spôsoby podpory vrátane kryptomienOdoslaním daru súhlasíte s našimi podmienkami prijímania darov.
Chcete to zabudovať do svojho produktu?
Naše balíky integrujeme do zákazkových Laravel a AI riešení. Napíšte nám, na čom pracujete, a ozveme sa do 48 hodín.